Skip to content

Unified UI and API for processing and training images for facial recognition.

License

Notifications You must be signed in to change notification settings

weitheng/double-take

 
 

Repository files navigation

Double Take Double Take Docker Pulls Discord

Double Take

Unified UI and API for processing and training images for facial recognition.

Why?

There's a lot of great open source software to perform facial recognition, but each of them behave differently. Double Take was created to abstract the complexities of the detection services and combine them into an easy to use UI and API.

Features

  • UI and API bundled into single Docker image
  • Ability to password protect UI and API
  • Support for multiple detectors
  • Train and untrain images for subjects
  • Process images from NVRs
  • Publish results to MQTT topics
  • REST API can be invoked by other applications

Supported Detectors

Supported NVRs

Integrations

Subscribe to Frigate's MQTT topics and process images for analysis.

mqtt:
  host: 192.168.1.1

frigate:
  url: http://192.168.1.1:5000

When the frigate/events topic is updated the API begins to process the snapshot.jpg and latest.jpg images from Frigate's API. These images are passed from the API to the configured detector(s) until a match is found that meets the configured requirements. To improve the chances of finding a match, the processing of the images will repeat until the amount of retries is exhausted or a match is found.

When the frigate/+/person/snapshot topic is updated the API will process that image with the configured detector(s). It is recommended to increase the MQTT snapshot size in the Frigate camera config.

cameras:
  front-door:
    mqtt:
      timestamp: False
      bounding_box: False
      crop: True
      height: 500

If a match is found the image is saved to /.storage/matches/${filename}.

Trigger automations / notifications when images are processed.

If the MQTT integration is configured within Home Assistant, then sensors will automatically be created.

Notification Automation

alias: Notify
trigger:
  - platform: state
    entity_id: sensor.double_take_david
  - platform: state
    entity_id: sensor.double_take_unknown
condition:
  - condition: template
    value_template: '{{ trigger.to_state.state != trigger.from_state.state }}'
action:
  - service: notify.mobile_app
    data:
      message: >-
        {{trigger.to_state.attributes.friendly_name}} is near the
        {{trigger.to_state.state}} @
        {{trigger.to_state.attributes.match.confidence}}% by
        {{trigger.to_state.attributes.match.detector}}:{{trigger.to_state.attributes.match.type}}
        taking {{trigger.to_state.attributes.attempts}} attempt(s) @
        {{trigger.to_state.attributes.duration}} sec
      data:
        attachment:
          url: http://192.168.1.2:3000/api/storage/matches/{{trigger.to_state.attributes.match.filename}}?box=true&token={{trigger.to_state.attributes.token}}
        actions:
          - action: URI
            title: View Image
            uri: http://192.168.1.2:3000/api/storage/matches/{{trigger.to_state.attributes.match.filename}}?box=true&token={{trigger.to_state.attributes.token}}

MQTT

Publish results to double-take/matches/${name} and double-take/cameras/${camera}. The number of results will also be published to double-take/cameras/${camera}/person and will reset back to 0 after 30 seconds.

mqtt:
  host: 192.168.1.1

double-take/matches/david

{
  "id": "1623906078.684285-5l9hw6",
  "duration": 1.26,
  "timestamp": "2021-06-17T05:01:36.030Z",
  "attempts": 3,
  "camera": "living-room",
  "zones": [],
  "match": {
    "name": "david",
    "confidence": 66.07,
    "match": true,
    "box": { "top": 308, "left": 1018, "width": 164, "height": 177 },
    "type": "latest",
    "duration": 0.28,
    "detector": "compreface",
    "filename": "2f07d1ad-9252-43fd-9233-2786a36a15a9.jpg"
  }
}

double-take/cameras/back-door

{
  "id": "ff894ff3-2215-4cea-befa-43fe00898b65",
  "duration": 4.25,
  "timestamp": "2021-06-17T03:19:55.695Z",
  "attempts": 5,
  "camera": "back-door",
  "zones": [],
  "matches": [
    {
      "name": "david",
      "confidence": 100,
      "match": true,
      "box": { "top": 286, "left": 744, "width": 319, "height": 397 },
      "type": "manual",
      "duration": 0.8,
      "detector": "compreface",
      "filename": "4d8a14a9-96c5-4691-979b-0f2325311453.jpg"
    }
  ]
}

Notify Services

notify:
  gotify:
    url: http://192.168.1.1:8080
    token: XXXXXXX

UI

The UI is accessible from http://localhost:3000.

  • Matches: /
  • Train: /train
  • Config: /config
  • Access Tokens: /tokens (if authentication is enabled)

Authentication

Enable authentication to password protect the UI. This is recommended if running Double Take behind a reverse proxy which is exposed to the internet.

auth: true

API

Documentation can be viewed on Postman.

Usage

Docker Run

docker run -d \
  --name=double-take \
  --restart=unless-stopped \
  -p 3000:3000 \
  -v ${PWD}/.storage:/.storage \
  jakowenko/double-take

Docker Compose

version: '3.7'

services:
  double-take:
    container_name: double-take
    image: jakowenko/double-take
    restart: unless-stopped
    volumes:
      - ${PWD}/.storage:/.storage
    ports:
      - 3000:3000

Configuration

Configurable options that can be passed by mounting a file at /double-take/config.yml and is editable via the UI at http://localhost:3000/#/config. Default values do not need to be specified in configuration unless they need to be overwritten.

mqtt:
  host: 192.168.1.1

frigate:
  url: http://192.168.1.1:5000

detectors:
  compreface:
    url: http://192.168.1.1:8000
    key: xxx-xxx-xxx-xxx-xxx # key from recognition service in created app
  deepstack:
    url: http://192.168.1.1:8001
    key: xxx-xxx-xxx-xxx-xxx # optional api key
  facebox:
    url: http://192.168.1.1:8002
Option Default Description
auth false Add authentication to UI and API
mqtt.host MQTT host
mqtt.username MQTT username
mqtt.password MQTT password
mqtt.topics.frigate frigate/events MQTT topic for Frigate message subscription
mqtt.topics.homeassistant homeassistant MQTT topic for Home Assistant Discovery subscription
mqtt.topics.matches double-take/matches MQTT topic where matches are published
mqtt.topics.cameras double-take/cameras MQTT topic where matches are published by camera name
confidence.match 60 Minimum confidence needed to consider a result a match
confidence.unknown 40 Minimum confidence needed before classifying a match name as unknown
objects.face.min_area_match 10000 Minimum area in pixels to consider a result a match
save.matches true Save match images
save.unknown true Save unknown images
purge.matches 168 Hours to keep match images until they are deleted
purge.unknown 8 Hours to keep unknown images until they are deleted
frigate.url Base URL for Frigate
frigate.attempts.latest 10 Amount of times API will request a Frigate latest.jpg for facial recognition
frigate.attempts.snapshot 0 Amount of times API will request a Frigate snapshot.jpg for facial recognition
frigate.image.height 500 Height of Frigate image passed for facial recognition
frigate.cameras Only process images from specific cameras
frigate.zones Only process images from specific zones
cameras.camera-name.snapshot.topic Process jpeg encoded topic for facial recognition
cameras.camera-name.snapshot.url Process HTTP image for facial recognition
detectors.compreface.url Base URL for CompreFace API
detectors.compreface.key API Key for CompreFace collection
detectors.compreface.det_prob_threshold 0.8 Minimum required confidence that a recognized face is actually a face. Value is between 0.0 and 1.0
detectors.compreface.face_plugins Comma-separated slugs of face plugins
detectors.deepstack.url Base URL for DeepStack API
detectors.deepstack.key API Key for DeepStack
detectors.facebox.url Base URL for Facebox API
notify.gotify.url Base URL for Gotify
notify.gotify.token Gotify application token Gotify
notify.gotify.priority 5 Gotify message priority
notify.gotify.cameras Only notify from specific cameras
notify.gotify.zones Only notify from specific zones
time.format Defaults to ISO 8601 format with support for token-based formatting
time.timezone UTC Time zone used in logs

Donations

If you would like to make a donation to support development, please use GitHub Sponsors.

About

Unified UI and API for processing and training images for facial recognition.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 56.6%
  • Vue 42.1%
  • Other 1.3%