blakeblackshear.frigate/README.md

154 lines
7.3 KiB
Markdown
Raw Normal View History

2019-12-08 14:03:58 +01:00
# Frigate - Realtime Object Detection for IP Cameras
Uses OpenCV and Tensorflow to perform realtime object detection locally for IP cameras. Designed for integration with HomeAssistant or others via MQTT.
2019-03-03 17:04:27 +01:00
2020-02-22 15:59:16 +01:00
Use of a [Google Coral USB Accelerator](https://coral.withgoogle.com/products/accelerator/) is optional, but highly recommended. On my Intel i7 processor, I can process 2-3 FPS with the CPU. The Coral can process 100+ FPS with very low CPU load.
- Leverages multiprocessing heavily with an emphasis on realtime over processing every frame
- Uses a very low overhead motion detection to determine where to run object detection
- Object detection with Tensorflow runs in a separate process
2019-03-30 13:58:31 +01:00
- Object info is published over MQTT for integration into HomeAssistant as a binary sensor
2020-02-22 15:59:16 +01:00
- An endpoint is available to view an MJPEG stream for debugging, but should not be used continuously
2019-03-03 17:04:27 +01:00
![Diagram](diagram.png)
2019-03-30 13:58:31 +01:00
## Example video (from older version)
2019-03-03 17:04:27 +01:00
You see multiple bounding boxes because it draws bounding boxes from all frames in the past 1 second where a person was detected. Not all of the bounding boxes were from the current frame.
[![](http://img.youtube.com/vi/nqHbCtyo4dY/0.jpg)](http://www.youtube.com/watch?v=nqHbCtyo4dY "Frigate")
2019-01-26 15:02:59 +01:00
## Getting Started
Run the container with
2020-02-22 15:59:16 +01:00
```bash
2019-02-10 21:25:30 +01:00
docker run --rm \
2019-03-30 13:58:31 +01:00
--privileged \
2020-02-22 15:59:16 +01:00
--shm-size=512m \ # should work for a 2-3 cameras
2019-03-30 13:58:31 +01:00
-v /dev/bus/usb:/dev/bus/usb \
2019-03-06 04:42:09 +01:00
-v <path_to_config_dir>:/config:ro \
2019-12-08 15:55:19 +01:00
-v /etc/localtime:/etc/localtime:ro \
2019-01-26 15:02:59 +01:00
-p 5000:5000 \
2019-12-08 14:03:58 +01:00
-e FRIGATE_RTSP_PASSWORD='password' \
2020-03-01 14:47:22 +01:00
blakeblackshear/frigate:stable
2019-01-26 15:02:59 +01:00
```
2019-03-03 17:04:27 +01:00
Example docker-compose:
2020-02-22 15:59:16 +01:00
```yaml
2019-02-28 13:49:27 +01:00
frigate:
container_name: frigate
restart: unless-stopped
2019-03-30 13:58:31 +01:00
privileged: true
2020-02-22 15:59:16 +01:00
shm_size: '1g' # should work for 5-7 cameras
2020-03-01 14:47:22 +01:00
image: blakeblackshear/frigate:stable
2019-02-28 13:49:27 +01:00
volumes:
2019-03-30 13:58:31 +01:00
- /dev/bus/usb:/dev/bus/usb
2019-12-08 15:55:19 +01:00
- /etc/localtime:/etc/localtime:ro
2019-02-28 13:49:27 +01:00
- <path_to_config>:/config
ports:
2019-03-30 13:58:31 +01:00
- "5000:5000"
2019-02-28 13:49:27 +01:00
environment:
2019-12-08 14:03:58 +01:00
FRIGATE_RTSP_PASSWORD: "password"
2019-02-28 13:49:27 +01:00
```
2019-12-09 08:51:42 +01:00
A `config.yml` file must exist in the `config` directory. See example [here](config/config.example.yml) and device specific info can be found [here](docs/DEVICES.md).
2019-03-06 04:42:09 +01:00
## Integration with HomeAssistant
2019-01-26 15:02:59 +01:00
Setup a the camera, binary_sensor, sensor and optionally automation as shown for each camera you define in frigate. Replace <camera_name> with the camera name as defined in the frigate `config.yml` (The `frigate_coral_fps` and `frigate_coral_inference` sensors only need to be defined once)
2020-02-22 15:59:16 +01:00
2019-03-03 17:04:27 +01:00
```
camera:
- name: <camera_name> Last Person
platform: mqtt
topic: frigate/<camera_name>/person/snapshot
- name: <camera_name> Last Car
platform: mqtt
topic: frigate/<camera_name>/car/snapshot
2019-03-03 17:04:27 +01:00
binary_sensor:
- name: <camera_name> Person
2019-03-03 17:04:27 +01:00
platform: mqtt
state_topic: "frigate/<camera_name>/person"
device_class: motion
2019-03-30 13:58:31 +01:00
availability_topic: "frigate/available"
2020-02-22 15:59:16 +01:00
sensor:
- platform: rest
name: Frigate Debug
resource: http://localhost:5000/debug/stats
scan_interval: 5
json_attributes:
- <camera_name>
2020-02-22 15:59:16 +01:00
- coral
value_template: 'OK'
- platform: template
sensors:
<camera_name>_fps:
value_template: '{{ states.sensor.frigate_debug.attributes["<camera_name>"]["fps"] }}'
2020-02-22 15:59:16 +01:00
unit_of_measurement: 'FPS'
<camera_name>_skipped_fps:
value_template: '{{ states.sensor.frigate_debug.attributes["<camera_name>"]["skipped_fps"] }}'
2020-02-22 15:59:16 +01:00
unit_of_measurement: 'FPS'
<camera_name>_detection_fps:
value_template: '{{ states.sensor.frigate_debug.attributes["<camera_name>"]["detection_fps"] }}'
2020-02-22 15:59:16 +01:00
unit_of_measurement: 'FPS'
frigate_coral_fps:
value_template: '{{ states.sensor.frigate_debug.attributes["coral"]["fps"] }}'
unit_of_measurement: 'FPS'
frigate_coral_inference:
value_template: '{{ states.sensor.frigate_debug.attributes["coral"]["inference_speed"] }}'
unit_of_measurement: 'ms'
automation:
- alias: Alert me if a person is detected while armed away
trigger:
platform: state
entity_id: binary_sensor.camera_person
from: 'off'
to: 'on'
condition:
- condition: state
entity_id: alarm_control_panel.home_alarm
state: armed_away
action:
- service: notify.user_telegram
data:
message: "A person was detected."
data:
photo:
- url: http://<ip>:5000/<camera_name>/person/best.jpg
caption: A person was detected.
2019-03-03 17:04:27 +01:00
```
## Debuging Endpoint
Access the mjpeg stream at `http://localhost:5000/<camera_name>` and the best snapshot for any object type with at `http://localhost:5000/<camera_name>/<object_name>/best.jpg`
You can access a higher resolution mjpeg stream by appending `h=height-in-pixels` to the endpoint. For example `http://localhost:5000/back?h=1080`. You can also increase the FPS by appending `fps=frame-rate` to the URL such as `http://localhost:5000/back?fps=10`
Keep in mind the MJPEG endpoint is for debugging only, but should not be used continuously as it will put additional load on the system.
Debug info is available at `http://localhost:5000/debug/stats`
2020-03-01 14:47:22 +01:00
## Using a custom model
Models for both CPU and EdgeTPU (Coral) are bundled in the image. You can use your own models with volume mounts:
- CPU Model: `/cpu_model.tflite`
- EdgeTPU Model: `/edgetpu_model.tflite`
- Labels: `/labelmap.txt`
2019-03-03 17:04:27 +01:00
2019-02-04 14:10:42 +01:00
## Tips
- Lower the framerate of the video feed on the camera to reduce the CPU usage for capturing the feed. Not as effective, but you can also modify the `take_frame` [configuration](config/config.example.yml) for each camera to only analyze every other frame, or every third frame, etc.
- Hard code the resolution of each camera in your config if you are having difficulty starting frigate or if the initial ffprobe for camerea resolution fails or returns incorrect info. Example:
```
cameras:
back:
ffmpeg:
input: rtsp://<camera>
height: 1080
width: 1920
```
- Object configuration - Tracked objects types, sizes and thresholds can be defined globally and/or on a per camera basis. The global and camera object configuration is *merged*. For example, if you defined tracking person, car, and truck globally but modified your backyard camera to only track person, the global config would merge making the effective list for the backyard camera still contain person, car and truck. If you want precise object tracking per camera, best practice to put a minimal list of objects at the global level and expand objects on a per camera basis. Object threshold and area configuration will be used first from the camera object config (if defined) and then from the global config. See the [example config](config/config.example.yml) for more information.
- Masks and limiting detection to a certain area - You can create a bitmap (bmp) file the same aspect ratio as your camera feed to limit detection to certain areas. The mask works by looking at the bottom center of any bounding box (red dot below) and comparing that to your mask.
<a href="docs/example-mask-check-point.png"><img src="docs/example-mask-check-point.png" height="300"></a>
If that red dot falls on an area of your mask that is black, the detection (and motion) will be ignored. Here is a sample mask that would limit detection to only the front yard and not the street for the above image:
<a href="docs/example-mask.bmp"><img src="docs/example-mask.bmp" height="300"></a>