Face detection with Docker/Machinebox

Something like:

- id: '12345'
  alias: Facebox recognised
  trigger:
    platform: event
    event_type: image_processing.detect_face
  action:
    service: notify.platform
    data_template:
      message: Recognised {{ trigger.event.data.name }}
      title: Door-cam notification

@robmarkcole Thanks for the tip. I had not installed this on the fresh environment Im using for Facebox. I shall try as soon as I am back home.

The reference to a separate machine was not a question, just saying what I am using in case it helps for troubleshooting.

I was letting you know of what I think is a bug: no error is reported when using an invalid IP or camera entity. Instead an image_processing entity is created with state: unknownā€¦

This morning I confirmed that the face detection works on all 3 cameras on my install. I noticed a strange behavior whereby the number of faces detected goes up just for an instant before going back to 0 until the next scan. This is sufficient to start an automation, but may not be what is needed for say a shop that need to count how many customers are present. The total_faces attribute should really stay at the max number between scans, shouldnā€™t it? Is what I am witnessing normal behaviour?

Would you rather have us open issues in GitHub or discuss through here?

@monkey-house yes please open an issue on Github and tag me in it. I havenā€™t tested extensively with multiple cameras so could be a bug.

Added stuff on GitHub for reference. Will try to use the latest custom_components or wait til 72.0ā€™s release in order to check on some of the issues noticed.

Thanks Robin for the facebox_python script. This works great for me, although it was a disappointment to see that Faceboxā€™s free license only allows for 20 different pictures, not strictly 20 different faces. Is everyone getting on well with just using one picture per person? If not how many pictures per person give food results?

1 Like

Iā€™ve had success with 1 training image, it all depends on the confidence threshold you want to achieve. Youā€™ve got to remember that Machinebox have a paid tier, and this free tier is a bonus. long term Iā€™d like to come up with a HA alternative to Facebox

1 Like

Iā€™m having no luck with the template sensor:

2018-06-21 12:57:55 ERROR (MainThread) [homeassistant.config] Invalid config for [sensor.template]: invalid template (TemplateSyntaxError: unexpected '>') for dictionary value @ data['sensors']['garden_detection']['value_template']. Got '{{ states.image_processing.garden.attributes.faces[0]["name"].title<> }}'
invalid template (TemplateSyntaxError: unexpected '>') for dictionary value @ data['sensors']['gate_detection']['value_template']. Got '{{ states.image_processing.gate.attributes.faces[0]["name"].title<> }}'
invalid template (TemplateSyntaxError: unexpected '>') for dictionary value @ data['sensors']['kitchen_detection']['value_template']. Got '{{ states.image_processing.kitchen.attributes.faces[0]["name"].title<> }}'
invalid template (TemplateSyntaxError: unexpected '>') for dictionary value @ data['sensors']['living_detection']['value_template']. Got '{{ states.image_processing.living.attributes.faces[0]["name"].title<> }}'. (See ?, line ?). Please check the docs at https://home-assistant.io/components/sensor.template/

Are other users using this with no issue?
@juan11perez: Am I doing something wrong?

Use the dev tool to check your template

@monkey-house
sorry, which template? please post it

Yea, sorry. I meant this one:

- platform: template
  sensors:
    gate_detection:
      friendly_name: 'Gate'
      value_template: '{{ states.image_processing.gate.attributes.faces[0]["name"].title<> }}'

The sensor kinda works like this:

    kitchen_detection:
      friendly_name: 'Kitchen'
      value_template: '{{ states.image_processing.kitchen.attributes.matched_faces }}'

Sensor returns ā€œ{}ā€ when no face is detected, ā€œunknownā€ when a face is detected, but not recognised and ā€œ{ā€˜Noaā€™: 0.69, ā€˜Lukeā€™: 0.57}ā€ when faces are recognised. Not terribly pretty, but works!

Here is the full state of the image_processing entity:

faces: [object Object],[object Object],[object Object]
total_faces: 3
matched_faces: {
  "Cedric": 0.66,
  "Luke": 0.69,
  "Noa": 0.72
}
friendly_name: Living
device_class: face

The info I really need in a sensor is the total number of faces in the image, the names of the faces recognised and the confidence level, ideally as a percentage. Got to brush up on my templating skillsā€¦ but any help is appreciated!

One of the use cases for this is to improve and refine presence detection from other devices like motion sensors, bluetooth tracker and mobile devices on a room by room basis and use this to trigger scenes.

@monkey-house
this is my sensor

- platform: template
  sensors:
    facebox_detection:
      friendly_name: 'Facebox Detection'
      value_template: '{{ states.image_processing.facebox_saved_images.attributes.faces[0]["name"].title() }}'

It gives the name of face [0]. I presume you can get face [1] and so forth.

the best way is as Rob says to use the dev tool. Paste
{{ states.image_processing.kitchen.attributes }} and add criteria after attributes. For instance

{{ states.image_processing.kitchen.attributes.total_faces }}

play around with it, till you get the desired output

1 Like

An event is fired every time a face is recognised, you could use an automation to increment a counter for each face. Info on using events has now been added to the docs

OK I added total_mathced_faces as an attribute in https://github.com/robmarkcole/HASS-Machinebox-Facebox/tree/adds-teach-service

1 Like

Thanks a lot for your time guys. I am experimenting. Just updated to the latest custom_component. Total matched faces works.

@juan11perezā€™s sensor works fine and outputs the name only as desired (tested with one face).

      value_template: '{{ states.image_processing.kitchen.faces[0]["name"].title() }}'

Testing for 2 faces as we speak, but no luck.

Now, sorry if Iā€™m thick, but is it possible to create a template sensor with more than one attribute or do we need to create several sensors with one attribute each?

Hackster.ioā€™s version has <> brackets at the end and this is why it did not work for me beforeā€¦

Remind me the point of this sensor? If you just want a record of matched faces the simplest thing to do is create a template sensor on {{states.image_processing.facebox_local_file.attributes.matched_faces}} or even {{states.image_processing.facebox_local_file.attributes.matched_faces.keys()}}

The idea is to use each camera for zone presence detection, say to answer queries like: ā€œWhere is Cedric?ā€ returning ā€œCedric is in the kitchenā€. Even as a doorbel type detection, this makes sense as you can output: ā€œCedric and Luke are at the doorā€.

The first face detected works like a charm. Tried to get a second face detected via a second sensor with this:

      value_template: '{{ states.image_processing.kitchen.faces[1]["name"].title() }}'

but the sensor output remains ā€œunknownā€ even with 2 faces detected.

Right now a second face matched will not show up on any template sensor even when one is present on the image_processing entity.

Adding ā€œ.keysā€ returns:

<built-in method keys of dict object at 0x7f2195c40ee8>

Will have to play around with the developer tools templates section as you guys suggested a while more. If I get a positive, Iā€™ll post back here.

Another way would be to do this directly in the component and have a logic where, if one face matched, write name in attribute face 1. If 2 faces matched, write names in attributes face 1 and face 2ā€¦ If no face matched, write none in attributes face 1, face 2, face 3, etcā€¦

Thanks again for the assistance!

Update:
Managed to get a second or third face detected to be output in a sensor as per Juanā€™s suggestion:

      value_template: '{{ states.image_processing.kitchen.faces[1]["name"].title() }}'

Now itā€™s a matter of finding the right templating structure. Iā€™m really struggling with the very complex matched_faces attributes. Here is the type of thing Iā€™d like to do:

>
{% if is_state_attr('states.image_processing.kitchen.attributes.faces[0]["name"].title() ', 'Unknown') %}
None
{% else %}
{{ states.image_processing.garden.attributes.faces[0]["name"].title() }}
{% endif %}

Then add ā€œand [ā€œnameā€]ā€ if more than one face is present.
A different attribute in the component for each matched face and storing the confidence level separately would make templating a breeze, even for noobs like me!

@monkey-house im not templating guru either :joy: but how about you create a ā€œconsolidatedā€ template sensor.
you have sensors for each face [1], [2] etc.
Then add a sensor that sort joins.
value_template: ā€˜{{ states.sensor_face1.state ā€œandā€ states.sensor_face2 }}ā€™

1 Like

You can use an automation to update the location of a person

1 Like

@juan11perez: Funny how you sometimes miss the obviousā€¦ I think you put me on the right path. Iā€™m surely learning loads about templating. It seems there are ways to get the info I need with no change to the component.
@robmarkcole: Once Iā€™ve finished messing around with templates, Iā€™ll look at automations. I guess creating a sensor called ā€œsensor.cedric_locationā€, whose status gets updated automatically once ā€œCedricā€ has been detected by Facebox on one of the camerasā€¦ Output could be ā€œCedric was last seen at 16:42 in the living roomā€!

Precisely. But also need to update if person not detected and thatā€™s not handled by the component currently

I think what matters is the last detection, unless the person has left home. Thereā€™s always going to be shadowy/non recorded areas in a home (and thatā€™s prob a good thing!)
Device_trackers (phone and/or bluetooth trackers) work well for home or away statusesā€¦

OK, here is what I came up with for room by room detection and recognition:

    gate_detection_1:
      friendly_name: 'Gate'
      value_template: '{{ states.image_processing.gate.attributes.faces[0]["name"].title() }}'
    gate_detection_2:
      friendly_name: 'Gate'
      value_template: '{{ states.image_processing.gate.attributes.faces[1]["name"].title() }}'
    gate_detection_3:
      friendly_name: 'Gate'
      value_template: '{{ states.image_processing.gate.attributes.faces[2]["name"].title() }}'
    gate_detection_4:
      friendly_name: 'Gate'
      value_template: '{{ states.image_processing.gate.attributes.faces[3]["name"].title() }}'
    gate_detection:
      friendly_name: 'Gate'
      value_template: >-
        {% if states.sensor.gate_detection_4.state != "unknown" %}  
          {{ states.image_processing.gate.attributes.total_faces }} face(s), including {{ states.sensor.gate_detection_1.state }}, {{ states.sensor.gate_detection_2.state }}, {{ states.sensor.gate_detection_3.state }} and {{ states.sensor.gate_detection_4.state }}, detected by the gate! 
        {% elif states.sensor.gate_detection_3.state != "unknown" %}  
          {{ states.image_processing.gate.attributes.total_faces }} face(s), including {{ states.sensor.gate_detection_1.state }}, {{ states.sensor.gate_detection_2.state }} and {{ states.sensor.gate_detection_3.state }}, detected by the gate! 
        {% elif states.sensor.gate_detection_2.state != "unknown" %} 
          {{ states.image_processing.gate.attributes.total_faces }} face(s), including {{ states.sensor.gate_detection_1.state }} and {{ states.sensor.gate_detection_2.state }}, detected by the gate!
        {% elif states.sensor.gate_detection_1.state != "unknown" %} 
          {{ states.image_processing.gate.attributes.total_faces }} face(s), including {{ states.sensor.gate_detection_1.state }}, detected by the gate! 
        {% elif states.image_processing.gate.attributes.total_faces > 0 %} 
          {{ states.image_processing.gate.attributes.total_faces }} face(s) detected by the gate! 
        {% else %} 
          No one detected by the gate!
        {% endif %}

That makes for a lot of sensors when you factor in 5 cameras, but seems to work for me so far. Of course, the matched_faces_total could be used for conditionals.
As for use cases, well, doorbell announcements, locating someone around a property, securing a property, automation triggers, etc. Itā€™s also good fun and Iā€™m looking forward to adding this to my floorplan component and room by room navigation!

1 Like