Looking for help parsing a State

I’m using tensorflow and it’s working great, I’m looking to be able to parse the state of the sensor and come up with a count of specific objects

For example here is the state of my camera at the moment

matches: {
  "person": [
    {
      "score": 96.79025411605835,
      "box": [
        0.21866311132907867,
        0.6428085565567017,
        0.34407034516334534,
        0.6730395555496216
      ]
    }
  ],
  "car": [
    {
      "score": 83.01277160644531,
      "box": [
        0.17965902388095856,
        0.439156174659729,
        0.3273550868034363,
        0.5330307483673096
      ]
    }
  ]
}
summary: {
  "person": 1,
  "car": 1
}
total_matches: 2
friendly_name: TensorFlow back_gate

Objects can be car, truck, van motor cycle, person, dog, cat, etc.

I want to know how many vehicles are in the image. I’m having trouble grasping the best way to get a total, that filters out some of the objects, not just a total count.

edit another example

	matches: {
  "bicycle": [
    {
      "score": 98.54578971862793,
      "box": [
        0.1737593561410904,
        0.5515616536140442,
        0.25360411405563354,
        0.6173633933067322
      ]
    }
  ],
  "car": [
    {
      "score": 91.31867289543152,
      "box": [
        0.1800970584154129,
        0.44176483154296875,
        0.3287076950073242,
        0.5345969200134277
      ]
    }
  ]
}
summary: {
  "bicycle": 1,
  "car": 1
}
total_matches: 2
friendly_name: TensorFlow back_gate

So I’m close, just dont know how to get value for each

For example this

       entity_id: image_processing.tensorflow_back_gate
        {% set m = state_attr('image_processing.tensorflow_back_gate', 'summary') %}
       {% set vehicle_count = 0 %}
        {% if m.car is defined %}
          {{ vehicle_count == (vehicle_count + m.car) }}
        {% endif %}
{{ vehicle_count }}
 {{m }}
{{ m.car }}

returns

          False
        
0
 {'bicycle': 1, 'car': 1}
1

try this assuming you want the summary of the car at the end and car is only mentioned twice.

{{ states.image_processing.tensorflow_back_gate.state.split(’“car”:’)[2 ][:2] | int }}

What if there was a car, two trucks, a person, and a dog, for example. And I just wanted the total of vehicles? ie 3

Did this give you the # of total cars?
{{ states.image_processing.tensorflow_back_gate.state.split(’“car”:’)[2 ][:2] | int }}

if so, add trucks

{{ states.image_processing.tensorflow_back_gate.state.split(’“truck”:’)[2 ][:2] | int + states.image_processing.tensorflow_back_gate.state.split(’“car”:’)[2 ][:2] | int }}

This might not work because I suspect that if there was 2 trucks, the string “truck:” will show up 3 times. There might be a split function that can take the last string instead of the 2nd.

this should work, -1 is the last string

{{ states.image_processing.tensorflow_back_gate.state.split(’“truck”:’)[-1 ][:2] | int + states.image_processing.tensorflow_back_gate.state.split(’“car”:’)[-1 ][:2] | int }}

Close, but with this

matches: {
  "car": [
    {
      "score": 95.04094123840332,
      "box": [
        0.20254577696323395,
        0.5886361002922058,
        0.32794591784477234,
        0.6868645548820496
      ]
    },
    {
      "score": 93.7804102897644,
      "box": [
        0.18755415081977844,
        0.46359583735466003,
        0.3254301846027374,
        0.5525462031364441
      ]
    }
  ]
}
summary: {
  "car": 2
}
total_matches: 2
friendly_name: TensorFlow back_gate

this

{{ states.image_processing.tensorflow_back_gate.state.split(’“truck”:’)[-1 ][:2] | int + states.image_processing.tensorflow_back_gate.state.split(’“car”:’)[-1 ][:2] | int }}

returned a value of 4

It’s easier to count the matches then to add the summery.

{{ state_attr('image_processing.tensorflow_back_gate', 'matches') | select('in', ['car','bicycle','truck','van','motorcycle', 'person','dog','cat']) | select('eq','score') | list | length }}

EDIT: That first template is for a single level dictionary. You have a multi-level. This will take some finagling.

{%- macro do(d) %}
{%- for k, v in d.items() %}
{%- for v2 in v %}
{%- set k2, v2 = v2 %}
{{- k }}{{ ',' if not loop.last else '' }}
{%- endfor %}
{{- ',' if not loop.last else '' }}
{%- endfor %}
{%- endmacro %}
{{ do(state_attr('image_processing.tensorflow_back_gate', 'matches')).split(',') | length }}
1 Like

I was just about to come here and comment that your first line seems to work, but it’s a bit hard to test since I dont always have cars, trucks, people, or dogs in the camera. haha. Thank you for taking the time to help, this looks great.

Thanks again, greatly appreciate you taking the time to help me. So the current loop you have, should get a count, but no longer filters based on objects, right?

Shouldn’t it be possible to get the value from the summary section?

summary: {
  "car": 2
}

Then to scan the summary for matches, and then add those #'s?

You can’t count while looping. Jinja limitation. That’s why this ass backwards macro way is required.

Thanks for the info. Sorry for asking the extra questions, so I did use the macro in my template test area and it returned a value, but I’m not understanding how it would only count cars, trucks, etc. but not people. Do I use the macro and the template together somehow?

Could a namespace be used to hold the counter variable for this application? You discussed its use in this thread and I was wondering why it it wouldn’t work here.

I tried that first but it wouldn’t increment. I’m not sure if namespace actually works. :man_shrugging:

Just got an idea. Try this:

{{ state_attr('image_processing.tensorflow_back_gate', 'summary').values() | sum }}

EDIT:

I didn’t realize that was a stipulation. My b.

try this:

{% set summary = state_attr('image_processing.tensorflow_back_gate', 'summary') %}
{{ dict(summary.items() | selectattr(0, 'in', ['car','truck'])).values() | sum }}
1 Like

Thanks, that worked perfectly

I’m doing this

  - service: input_number.set_value
    data_template:
      entity_id: input_number.vehicles_in_driveway
      value:  >-
        {% if states('image_processing.back_yard')| int  > 0  %}
          {% set summary = state_attr('image_processing.back_yard', 'summary') %}
          {{ dict(summary.items() | selectattr(0, 'in', ['car','truck', 'van', 'motorcycle'])).values() | sum }}
        {% else %}
          0
        {% endif %}

When everyone leaves, count the number of vehicles and then I get notified if the number increases.

Thanks!

Let me tell you… that template was finagled.

EDIT: what camera are you using?

Ha ha. I just appreciate the help. I’m using a LaView camera. It’s basically a rebranded Hikvision. Then I’m using the recent tensorflow component. It’s working prettty great. The best part is that I now only get valid alerts for things I care about.

does the camera handle the image processing for item recognition? Or is that software?