forked from Github/frigate
Compare commits
34 Commits
v0.5.0-rc4
...
v0.4.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ea0eeda06 | ||
|
|
94878315ae | ||
|
|
8dab9e17dd | ||
|
|
5b2470e91e | ||
|
|
3d5faa956c | ||
|
|
b615b84f57 | ||
|
|
6f7b70665b | ||
|
|
3a5cb465fe | ||
|
|
205b8b413f | ||
|
|
1b74d7a19f | ||
|
|
b18e8ca468 | ||
|
|
9ebe186443 | ||
|
|
e580aca440 | ||
|
|
191f293037 | ||
|
|
d31ba69b1b | ||
|
|
02e1035826 | ||
|
|
3d419a39a8 | ||
|
|
474a3e604d | ||
|
|
fc757ad04f | ||
|
|
2a86d3e2e8 | ||
|
|
3e374ceb5f | ||
|
|
0b8f2cadf3 | ||
|
|
42f666491a | ||
|
|
35771b3444 | ||
|
|
2010ae8f87 | ||
|
|
fb0f6bcfae | ||
|
|
7b1da388d9 | ||
|
|
5d0c12fbd4 | ||
|
|
a43fd96349 | ||
|
|
bf94fdc54d | ||
|
|
48b3f22866 | ||
|
|
36443980ea | ||
|
|
0f8f8fa3b3 | ||
|
|
d8a3f8fc9d |
@@ -1,4 +1,4 @@
|
||||
FROM ubuntu:18.04
|
||||
FROM debian:stretch-slim
|
||||
LABEL maintainer "blakeb@blakeshome.com"
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
@@ -16,7 +16,7 @@ RUN apt -qq update && apt -qq install --no-install-recommends -y \
|
||||
# pillow-simd
|
||||
# zlib1g-dev libjpeg-dev \
|
||||
# VAAPI drivers for Intel hardware accel
|
||||
libva-drm2 libva2 i965-va-driver vainfo \
|
||||
i965-va-driver vainfo \
|
||||
&& echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" > /etc/apt/sources.list.d/coral-edgetpu.list \
|
||||
&& wget -q -O - https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - \
|
||||
&& apt -qq update \
|
||||
|
||||
@@ -81,12 +81,6 @@ cameras:
|
||||
# hwaccel_args: []
|
||||
# input_args: []
|
||||
# output_args: []
|
||||
|
||||
################
|
||||
## Optionally specify the resolution of the video feed. Frigate will try to auto detect if not specified
|
||||
################
|
||||
# height: 1280
|
||||
# width: 720
|
||||
|
||||
################
|
||||
## Optional mask. Must be the same dimensions as your video feed.
|
||||
@@ -106,19 +100,7 @@ cameras:
|
||||
take_frame: 1
|
||||
|
||||
################
|
||||
# The number of seconds frigate will allow a camera to go without sending a frame before
|
||||
# assuming the ffmpeg process has a problem and restarting.
|
||||
################
|
||||
# watchdog_timeout: 300
|
||||
|
||||
################
|
||||
# Configuration for the snapshot sent over mqtt
|
||||
################
|
||||
snapshots:
|
||||
show_timestamp: True
|
||||
|
||||
################
|
||||
# Camera level object config. This config is merged with the global config above.
|
||||
# Overrides for global object config
|
||||
################
|
||||
objects:
|
||||
track:
|
||||
|
||||
@@ -88,30 +88,21 @@ class DetectedObjectsProcessor(threading.Thread):
|
||||
obj['clipped'] = True
|
||||
|
||||
# Compute the area
|
||||
# TODO: +1 right?
|
||||
obj['area'] = (obj['box']['xmax']-obj['box']['xmin'])*(obj['box']['ymax']-obj['box']['ymin'])
|
||||
|
||||
self.camera.detected_objects[frame['frame_time']].append(obj)
|
||||
|
||||
# TODO: use in_process and processed counts instead to avoid lock
|
||||
with self.camera.regions_in_process_lock:
|
||||
if frame['frame_time'] in self.camera.regions_in_process:
|
||||
self.camera.regions_in_process[frame['frame_time']] -= 1
|
||||
self.camera.regions_in_process[frame['frame_time']] -= 1
|
||||
# print(f"{frame['frame_time']} remaining regions {self.camera.regions_in_process[frame['frame_time']]}")
|
||||
|
||||
if self.camera.regions_in_process[frame['frame_time']] == 0:
|
||||
del self.camera.regions_in_process[frame['frame_time']]
|
||||
# print(f"{frame['frame_time']} no remaining regions")
|
||||
self.camera.finished_frame_queue.put(frame['frame_time'])
|
||||
else:
|
||||
if self.camera.regions_in_process[frame['frame_time']] == 0:
|
||||
del self.camera.regions_in_process[frame['frame_time']]
|
||||
# print(f"{frame['frame_time']} no remaining regions")
|
||||
self.camera.finished_frame_queue.put(frame['frame_time'])
|
||||
|
||||
# Thread that checks finished frames for clipped objects and sends back
|
||||
# for processing if needed
|
||||
# TODO: evaluate whether or not i really need separate threads/queues for each step
|
||||
# given that only 1 thread will really be able to run at a time. you need a
|
||||
# separate process to actually do things in parallel for when you are CPU bound.
|
||||
# threads are good when you are waiting and could be processing while you wait
|
||||
class RegionRefiner(threading.Thread):
|
||||
def __init__(self, camera):
|
||||
threading.Thread.__init__(self)
|
||||
@@ -369,9 +360,6 @@ class ObjectTracker(threading.Thread):
|
||||
# than the number of existing object centroids we need to
|
||||
# register each new input centroid as a trackable object
|
||||
# if D.shape[0] < D.shape[1]:
|
||||
# TODO: rather than assuming these are new objects, we could
|
||||
# look to see if any of the remaining boxes have a large amount
|
||||
# of overlap...
|
||||
for col in unusedCols:
|
||||
self.register(col, group[col])
|
||||
|
||||
@@ -411,8 +399,7 @@ class BestFrames(threading.Thread):
|
||||
obj['box']['xmax'], obj['box']['ymax'], obj['name'], "{}% {}".format(int(obj['score']*100), obj['area']))
|
||||
|
||||
# print a timestamp
|
||||
if self.camera.snapshot_config['show_timestamp']:
|
||||
time_to_show = datetime.datetime.fromtimestamp(obj['frame_time']).strftime("%m/%d/%Y %H:%M:%S")
|
||||
cv2.putText(best_frame, time_to_show, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, fontScale=.8, color=(255, 255, 255), thickness=2)
|
||||
time_to_show = datetime.datetime.fromtimestamp(obj['frame_time']).strftime("%m/%d/%Y %H:%M:%S")
|
||||
cv2.putText(best_frame, time_to_show, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, fontScale=.8, color=(255, 255, 255), thickness=2)
|
||||
|
||||
self.best_frames[name] = best_frame
|
||||
@@ -11,7 +11,6 @@ import numpy as np
|
||||
import prctl
|
||||
import copy
|
||||
import itertools
|
||||
import json
|
||||
from collections import defaultdict
|
||||
from frigate.util import tonumpyarray, LABELS, draw_box_with_label, calculate_region, EventsPerSecond
|
||||
from frigate.object_detection import RegionPrepper, RegionRequester
|
||||
@@ -43,29 +42,8 @@ class FrameTracker(threading.Thread):
|
||||
del self.recent_frames[k]
|
||||
|
||||
def get_frame_shape(source):
|
||||
ffprobe_cmd = " ".join([
|
||||
'ffprobe',
|
||||
'-v',
|
||||
'panic',
|
||||
'-show_error',
|
||||
'-show_streams',
|
||||
'-of',
|
||||
'json',
|
||||
'"'+source+'"'
|
||||
])
|
||||
print(ffprobe_cmd)
|
||||
p = sp.Popen(ffprobe_cmd, stdout=sp.PIPE, shell=True)
|
||||
(output, err) = p.communicate()
|
||||
p_status = p.wait()
|
||||
info = json.loads(output)
|
||||
print(info)
|
||||
|
||||
video_info = [s for s in info['streams'] if s['codec_type'] == 'video'][0]
|
||||
|
||||
if video_info['height'] != 0 and video_info['width'] != 0:
|
||||
return (video_info['height'], video_info['width'], 3)
|
||||
|
||||
# fallback to using opencv if ffprobe didnt succeed
|
||||
# capture a single frame and check the frame shape so the correct array
|
||||
# size can be allocated in memory
|
||||
video = cv2.VideoCapture(source)
|
||||
ret, frame = video.read()
|
||||
frame_shape = frame.shape
|
||||
@@ -87,7 +65,7 @@ class CameraWatchdog(threading.Thread):
|
||||
# wait a bit before checking
|
||||
time.sleep(10)
|
||||
|
||||
if self.camera.frame_time.value != 0.0 and (datetime.datetime.now().timestamp() - self.camera.frame_time.value) > self.camera.watchdog_timeout:
|
||||
if self.camera.frame_time.value != 0.0 and (datetime.datetime.now().timestamp() - self.camera.frame_time.value) > 300:
|
||||
print(self.camera.name + ": last frame is more than 5 minutes old, restarting camera capture...")
|
||||
self.camera.start_or_restart_capture()
|
||||
time.sleep(5)
|
||||
@@ -173,15 +151,8 @@ class Camera:
|
||||
camera_objects_config = config.get('objects', {})
|
||||
|
||||
self.take_frame = self.config.get('take_frame', 1)
|
||||
self.watchdog_timeout = self.config.get('watchdog_timeout', 300)
|
||||
self.snapshot_config = {
|
||||
'show_timestamp': self.config.get('snapshots', {}).get('show_timestamp', True)
|
||||
}
|
||||
self.regions = self.config['regions']
|
||||
if 'width' in self.config and 'height' in self.config:
|
||||
self.frame_shape = (self.config['height'], self.config['width'], 3)
|
||||
else:
|
||||
self.frame_shape = get_frame_shape(self.ffmpeg_input)
|
||||
self.frame_shape = get_frame_shape(self.ffmpeg_input)
|
||||
self.frame_size = self.frame_shape[0] * self.frame_shape[1] * self.frame_shape[2]
|
||||
self.mqtt_client = mqtt_client
|
||||
self.mqtt_topic_prefix = '{}/{}'.format(mqtt_prefix, self.name)
|
||||
|
||||
Reference in New Issue
Block a user