New Custom Compontent - Image Processing - Object Detection - DOODS

One option would be to measure it. You open the camera image in an image editor where you have a ruler, and then you can translate that into the percentages of the image you need to use.
However trial and error is just fine as well. DOODS will include the box in its output so it is very easy to adjust afterwards.

Is there any way to turn off doods on the fly?

I want to disable it while I’m home to save resources on the host. I don’t have any triggers on my cameras to let doods know it should scan, so the image_processing.scan won’t work.

If I could change the scan_interval on the fly but it doesn’t look like it’s an option.

A python script to directly turn off/on the container?

I use presence detection along with node red to avoid running when I’m home.

Thanks snowzach, and thanks for the awesome component!

What is the command you use for not running?

I set the scan_inverval to 10000 seconds and then use camera motion to trigger the scan but avoid it if I am home. I don’t have anything to show you, it’s not a simple thing to setup. Google for Node Red automations if you want to do it that way.

Ok cool, I’ll work something out, thanks.

Is there a way to create polygon areas, as opposed to just defing distances from the edges?

Hello. Anyone know what the last 5 lines actually mean?

2021-03-09T18:37:17.940Z        INFO    detector/detector.go:79 Configured Detector     {"package": "detector", "name": "tensorflow", "type": "tensorflow", "model": "models/faster_rcnn_inception_v2_coco_2018_01_28.pb", "labels": 65, "w
idth": -1, "height": -1}                                                                                                                                                                                                                   
2021-03-09T18:37:17.942Z        INFO    server/server.go:284    API Listening   {"package": "server", "address": ":8080", "tls": false, "version": "v0.2.6-0-gb2a1c53-dirty"}                                                              
2021-03-09T18:37:31.258Z        INFO    server/server.go:139    HTTP Request    {"status": 404, "took": 0.000054763, "request": "/", "method": "GET", "package": "server.request", "request-id": "d3bbd70bdd51/ysAXebL0YF-000001", "remote"
: "10.0.3.1:37782"}                                                                                                                                                                                                                        
2021-03-09T18:40:36.568Z        INFO    server/server.go:139    HTTP Request    {"status": 404, "took": 0.000042225, "request": "/", "method": "GET", "package": "server.request", "request-id": "d3bbd70bdd51/ysAXebL0YF-000002", "remote"
: "10.0.3.1:42800"}                                                                                                                                                                                                                        
2021-03-09T18:40:41.441Z        INFO    server/server.go:139    HTTP Request    {"status": 404, "took": 0.000040275, "request": "/", "method": "GET", "package": "server.request", "request-id": "d3bbd70bdd51/ysAXebL0YF-000003", "remote"
: "10.0.3.1:42958"}                                                                                                                                                                                                                        
2021-03-09T18:47:26.576Z        INFO    server/server.go:139    HTTP Request    {"status": 404, "took": 0.000076463, "request": "/", "method": "GET", "package": "server.request", "request-id": "d3bbd70bdd51/ysAXebL0YF-000004", "remote"
: "10.0.3.1:54462"}                                                                                                                                                                                                                        
2021-03-09T18:47:30.459Z        INFO    server/server.go:139    HTTP Request    {"status": 404, "took": 0.000043625, "request": "/", "method": "GET", "package": "server.request", "request-id": "d3bbd70bdd51/ysAXebL0YF-000005", "remote"
: "10.0.3.1:54748"}

Just trying to understand what those requests are and who’s making them?

I’m running doods in docker on a QNAP NAS, alongside home-assistant (in docker as well), but the HA docker was not running at all at the time. I also can’t figure out what the 10.0.3.1 IP is, there’s no docker with that IP (doods’ docker IP seems to be 10.0.3.2)

Late response, but it might help so here goes…

I had the same problem with Wyze cams. The logs of doods always returned status 400. Switching on file_out (image_processing) never generated a file. My problem was that DOODS processes the stlil_image_url rather than the stream.

Switching to the ffmpeg camera platform solved this all. My working config below;

stream:
camera:
   - platform: ffmpeg
     name: Backyard
     input: rtsp://top:[email protected]:554/live

image_processing:
  - platform: doods
    scan_interval: 10
    url: http://doods.docker.lan:8081
    detector: default
    file_out: /config/www/doods.jpg
    source:
      - entity_id: camera.backyard

It’s set up and working now. Currently it thinks my door is a refrigerator, my mouse is a remote, my belly is a chair but the highest probability was me as a person so that’ll do!

hi there, first many thanks to snowzach for sharing his work and knowledge :slight_smile:

My HW/SW config: Raspy4, HA on docker, doods on docker, 4 outside cameras, doods scan_interval set to 10000 then on triggering motion a camera image gets downloaded and then doods can handle it.
After struggling with settings and so on to get this going I came to the same conclusion of many others here: default detector is quite unreliable and tensor flow is much too slow (the second camera triggering the process while another process of another camera is running may need up to 22 seconds). Now my questions to the community:
1-as already mentioned I installed doods on docker but I saw here that there should be a doods addon which I was not able to locate
2-How will I know there is an updated doods docker image to install (apart from frequently look on the Github site) and how to do this upgrade, do I have to follow again the whole install procedure?
3-are there other models to try? I saw there is a script to download a couple of them but I wouldn’t know how to implement them after downloading and if they are thought to work on Raspberry
4-I now have to evaluate the purchase of a coral device (very expensive) but @snowzach what do you mean with “garbage quality” with the EdgeTPU? Is it only about the rendered image but the “recognition process” is still good while much faster?
5-@snowzach I saw you are working on a PyTorch version, is this still a “work in progress” or did you gave up?

Well quite a lot of stuff and I will appreciate any kind of help even if only partial Thank you all

This is a fantastic component, thanks @snowzach

I have been setting the scan_interval to 10000 and using automation to call the service every 10s. In the automation, I measure the time for the service call by using a counter to “count starts”, “count stops” and then build a sensor to look a the last update times of those counters. I also extract the processing time from the DOODs result.

I am running DOODs with detector: tensorflow, looking to 60% confidence of 8 labels. The service call seems to have a really high overhead, much more than DOODs. I have done this two ways

First - I installed DOODs on the RP 4 running HASSIO
=> I see DOODs running for several seconds, but the service call lasts for over 10 and I can’t reliably run the automation more than every 20s

Second - I installed DOODs on my full descktop machine.
=> DOODs run times are 250 - 400ms, the service call lasts 4 seconds! So I am still only able to run the automation every 10s.

Where is all the lost time?

I am doing this concurrently for the 1920x1080 and 640x352 camera streams (same camera). The DOODs processing time is only marginally higher for the hires stream.

sensor:
  - platform: template
      object_detect_time_1920x1080:
        unit_of_measurement: "mS"
        value_template: "{{ state_attr('image_processing.doods_ipcam_1920x1080', 'process_time')|float * 1000 }}"
      doods_runtime_1920x1080:
        unit_of_measurement: "S"
        value_template: >-
          {% set runtime = as_timestamp(states.counter.doods_1920x1080_start.last_changed)- as_timestamp(states.counter.doods_1920x1080_stop.last_changed) %}
          {% if runtime > 0 -%}
            {{ runtime }}
          {%- else -%}
            {{ 0.0 }}
          {%- endif -%}

I have seen this before depending on the camera type… If it’s the kind of camera where when it needs to grab a frame it needs to connect to the camera and listen long enough to capture a full frame it can take a few seconds. I can’t remember the camera type in hass that did it but I definitely remember having a similar problem. If you’re camera has a still url and you supply that to the camera component it can help. Tensorflow takes pretty close to the same amount of time no matter the image size. It’s just how it works. Higher res is usually better in most cases.

Maybe a stupid question, but I don’t really understand what labels the default model can detect. I’m using the HA addon, since I don’t really understand Docker enough to just run a Docker image.

Is there a place where I can find the supported labels for the default model and how to add a different model?

Here is the section in the repo where you can view the default labels:

If you don’t understand docker, it’s probably going to be a bit involved to try to explain how to add more models. You can see in that linked repo how to do the basics of it. With that said, in my experience there really isn’t any models that work better than the 2 included unless you train your own… which is a whole thing in and of itself.

Then am I doing something wrong? It has no problem detecting me at over 80% confidence. However, it never detects my cat. I have now updated the config with lots of other items, but it doesn’t recognize any of them, even at 10% confidence. I have done this with the tensorflow model, but also the default model doesn’t work. My install method is the HA plugin.

I’m really surprised because I expected that at 10% confidence, it would tag my face as a cat, a wineglass and broccoli at the same time!

What am I missing here?

A screenshot is below. You can clearly see my cat, the wine bottle and the glass on the table.

Config:

image_processing:
  - platform: doods
    scan_interval: 120
    url: "http://192.168.1.252:8080"
    detector: default
    file_out:
      - "/tmp/{{ camera_entity.split('.')[1] }}_latest.jpg"
      - "/config/www/snapshots/persondetection/{{ states('sensor.date') }}/{{ camera_entity.split('.')[1] }}_{{ now().strftime('%Y%m%d_%H%M%S') }}.jpg"
      - "/config/www/snapshots/persondetection/live_feed/person_detection_feed.jpg"
    source:
      - entity_id: camera.tapo_camera_d6d4_hd
    confidence: 50
    labels:
      - name: person
        confidence: 60
        area:
          top: 0.25
          right: 0.45
      - name: cat
        confidence: 10
      - name: bottle
        confidence: 10
      - name: wine glass
        confidence: 10
      - name: broccoli
        confidence: 10
      - name: toothbrush
        confidence: 10

Assuming you’re using the default config, set the detector to tensorflow and then set the environment variable LOGGER_LEVEL=debug on the DOODS container and look at the logs there. It should show you everything it sees in the image regardless of the config.

Thanks for the quick reply!

Where would I do that? Just in the HA plugin?

Currently my config is:

server:
  port: '8080'
auth_key: ''
doods.detectors:
  - name: default
    type: tflite
    modelFile: /opt/doods/models/coco_ssd_mobilenet_v1_1.0_quant.tflite
    labelFile: /opt/doods/models/coco_labels0.txt
    numThreads: 1
    numConcurrent: 1
    hwAccel: false
  - name: tensorflow
    type: tensorflow
    modelFile: /opt/doods/models/faster_rcnn_inception_v2_coco_2018_01_28.pb
    labelFile: /opt/doods/models/coco_labels1.txt
    numThreads: 1
    numConcurrent: 1
    hwAccel: false

Should I just add a line logger_level: DEBUG?

For that one it’s

logger:
  level: debug

Are you sure? This is now my config:

server:
  port: '8080'
auth_key: ''
doods.detectors:
  - name: default
    type: tflite
    modelFile: /opt/doods/models/coco_ssd_mobilenet_v1_1.0_quant.tflite
    labelFile: /opt/doods/models/coco_labels0.txt
    numThreads: 1
    numConcurrent: 1
    hwAccel: false
  - name: tensorflow
    type: tensorflow
    modelFile: /opt/doods/models/faster_rcnn_inception_v2_coco_2018_01_28.pb
    labelFile: /opt/doods/models/coco_labels1.txt
    numThreads: 1
    numConcurrent: 1
    hwAccel: false
logger:
  level: debug

But when I look at the options.json file in the addon data directory of home assistant, I see this:

{
  "server": {
    "port": 8080
  },
  "auth_key": "",
  "doods.detectors": [
    {
      "name": "default",
      "type": "tflite",
      "modelFile": "/opt/doods/models/coco_ssd_mobilenet_v1_1.0_quant.tflite",
      "labelFile": "/opt/doods/models/coco_labels0.txt",
      "numThreads": 1,
      "numConcurrent": 1,
      "hwAccel": false
    },
    {
      "name": "tensorflow",
      "type": "tensorflow",
      "modelFile": "/opt/doods/models/faster_rcnn_inception_v2_coco_2018_01_28.pb",
      "labelFile": "/opt/doods/models/coco_labels1.txt",
      "numThreads": 1,
      "numConcurrent": 1,
      "hwAccel": false
    }
  ]
}

The logger setting is nowhere to be found.

Uggg… it might be the config validation stuff that’s part that’s part of hass.io… can you just set an environment variable on the container? Sorry, I don’t use it much so I don’t know it off the top of my head. The env variable is LOGGER_LEVEL=debug