ljmerza / frigate_plate_recognizer

Identify license plates via Plate Recognizer and add them as sublabels to Frigate
106 stars 13 forks source link

Save Images to Server #21

Closed gadget-man closed 5 months ago

gadget-man commented 6 months ago

Hi,

Is there a way to save the image sent to PlateRecognizer (showing the numberplate detected), either when a plate is detected, or optionally on every detection request (even if no plate recognised)? There is a similar feature on https://github.com/robmarkcole/HASS-plate-recognizer but frigate_plate_recognizer seems much more efficient (and quick) so I'm not really using the HA version anymore, but really missing having a folder with all the saved plate data on it!

gadget-man commented 6 months ago

I've taken a fork of the repo and have been working on some tweaks to the code to allow this. Will hopefully push a PR for review in the next few days, just need to do a bit more testing.

kyle4269 commented 6 months ago

I've taken a fork of the repo and have been working on some tweaks to the code to allow this. Will hopefully push a PR for review in the next few days, just need to do a bit more testing.

I did check out your current fork. I like how it draws a rectangle around the license plate with the plate number.

DrSpaldo commented 6 months ago

This would be a nice addition. I would love a way to keep all plates, recognised or not. Even better would be an easy way to search by plate...

gadget-man commented 6 months ago

I've added a PR for this: https://github.com/ljmerza/frigate_plate_recognizer/pull/24

@DrSpaldo I didn't do anything to allow saving by plate. However an easy solution would be to add the recognised plate in the filename of the saved snapshot?

DrSpaldo commented 6 months ago

I've added a PR for this: #24

@DrSpaldo I didn't do anything to allow saving by plate. However an easy solution would be to add the recognised plate in the filename of the saved snapshot?

Nice PR @gadget-man :)

Um, I’m not sure the best way but that wouldn’t be a bad idea?

gadget-man commented 6 months ago

I've tweaked the PR so that if a plate is recognised, it will add it to the file path when save_timestamped_file: True

ljmerza commented 6 months ago

added to v1.8.0

DrSpaldo commented 6 months ago

I am not sure if I have configured it incorrectly or what is happening. I am using Unraid, so I was previously using the config that is similar to Synology. I am getting the following errors when I start the container/stack:

File "/usr/src/app/./index.py", line 143
if not config['frigate'].get('save_snapshots', False)
^
SyntaxError: invalid syntax
File "/usr/src/app/./index.py", line 143
if not config['frigate'].get('save_snapshots', False)
^
SyntaxError: invalid syntax
File "/usr/src/app/./index.py", line 143
if not config['frigate'].get('save_snapshots', False)
^
SyntaxError: invalid syntax
File "/usr/src/app/./index.py", line 143
if not config['frigate'].get('save_snapshots', False)
^
SyntaxError: invalid syntax
File "/usr/src/app/./index.py", line 143
if not config['frigate'].get('save_snapshots', False)
^
SyntaxError: invalid syntax
File "/usr/src/app/./index.py", line 143
if not config['frigate'].get('save_snapshots', False)
^
SyntaxError: invalid syntax
File "/usr/src/app/./index.py", line 143
if not config['frigate'].get('save_snapshots', False)
^
SyntaxError: invalid syntax

Here is my stack compose file:

services:
  frigate_plate_recognizer:
    image: lmerza/frigate_plate_recognizer:latest
    container_name: frigate_plate_recognizer
    volumes:
      - /mnt/user/appdata/plate-recognizer/config:/usr/src/app/config
      - /mnt/user/appdata/plate-recognizer/plates:/usr/src/app/plates:rw
    restart: unless-stopped
    environment:
      - TZ=Australia/Brisbane

Here is my config.yaml:

frigate:
  frigate_url: http://192.168.2.20:5000
  mqtt_server: 192.168.2.20
  mqtt_auth: true
  mqtt_username: mosquitto
  mqtt_password: PASSWORD
  main_topic: frigate
  return_topic: plate_recognizer
  frigate_plus: false
  camera:
    - street3
  objects:
    - car
  min_score: .7
  save_snapshots: true
  draw_box: true
  always_save_snapshot: true
code_project:
  api_url: http://192.168.1.28:32168/v1/image/alpr
logger_level: INFO
DrSpaldo commented 6 months ago

@gadget-man @ljmerza Also tried running it in Portainer. Still getting the same error messages

gadget-man commented 6 months ago

there are quite a few changes in the finalised 1.8.0 that differ from my PR. For example, all references to always_save_snapshot have been removed, it no longer includes the Plate ID in the filename etc.

I'm still running the version based on my PR. Let me try 1.8.0 and see if I can replicate your problem.

gadget-man commented 6 months ago

Yep, to confirm, I'm getting the same issue on 1.8.0. @ljmerza can you please check?

kyle4269 commented 6 months ago

I think we need a : after

if not config['frigate'].get('save_snapshots', False)

If I'm not mistaken it should be

if not config['frigate'].get('save_snapshots', False):
DrSpaldo commented 6 months ago

Yep, to confirm, I'm getting the same issue on 1.8.0. @ljmerza can you please check?

Glad I wasn’t going crazy!

gadget-man commented 6 months ago

I think we need a : after

if not config['frigate'].get('save_snapshots', False)

If I'm not mistaken it should be

if not config['frigate'].get('save_snapshots', False):

Well spotted! Yep, that'll be it.

ljmerza commented 6 months ago

fixed in 1.8.1. there were a few edges cases around users not having frigate+ or no plate recognized that needed to be handled. dont have much time so didnt want to go back and forth in the PR. thanks for the work on this

gadget-man commented 6 months ago

Sorry, just ran a check and still not working:

2024/01/13 18:04:42 stderr UnboundLocalError: local variable 'frigate_url' referenced before assignment
2024/01/13 18:04:42 stderr snapshot_url = f"{frigate_url}/api/events/{frigate_event}/snapshot.jpg"
2024/01/13 18:04:42 stderr File "/usr/src/app/./index.py", line 215, in on_message=
gadget-man commented 6 months ago

Looks like frigate_url is now being referenced in 215 but it's not declared until line 240.

ljmerza commented 6 months ago

sorry about that. forget python doesnt eval syntax errors until runtime. fixed in 1.8.2

ljmerza commented 6 months ago

added a bunch of tests and found some other bugs. pushed v1.8.3 hopefully this is it. need to add more tests in the future

DrSpaldo commented 6 months ago

Thanks for looking at it @ljmerza and doing the new builds. I am testing it now...

I am getting the following error continually every time a plate is detected:

2024-01-14 11:54:51,040 - __main__ - INFO - Time: 2024-01-14 11:54:51.040
2024-01-14 11:54:51,040 - __main__ - INFO - Python Version: 3.9.18 (main, Jan 11 2024, 11:28:41)

[GCC 12.2.0]
2024-01-14 11:54:51,040 - __main__ - INFO - Frigate Plate Recognizer Version: 1.8.3

2024-01-14 11:54:51,040 - __main__ - INFO - Using CodeProject.AI API
2024-01-14 11:54:51,040 - __main__ - INFO - Starting MQTT client. Connecting to: 192.168.2.20
2024-01-14 11:54:51,041 - __main__ - INFO - MQTT Connected
Traceback (most recent call last):
File "/usr/src/app/./index.py", line 403, in <module>
main()
File "/usr/src/app/./index.py", line 399, in main
run_mqtt_client()
File "/usr/src/app/./index.py", line 358, in run_mqtt_client
mqtt_client.loop_forever()
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 1756, in loop_forever
rc = self._loop(timeout)
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 1164, in _loop
rc = self.loop_read()
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 1556, in loop_read
rc = self._packet_read()
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 2439, in _packet_read
rc = self._packet_handle()
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 3033, in _packet_handle
return self._handle_publish()
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 3327, in _handle_publish
self._handle_on_message(message)
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 3570, in _handle_on_message
on_message(self, self._userdata, message)
File "/usr/src/app/./index.py", line 215, in on_message
snapshot_url = f"{frigate_url}/api/events/{frigate_event}/snapshot.jpg"
UnboundLocalError: local variable 'frigate_event' referenced before assignment
2024-01-14 11:55:40,242 - __main__ - INFO - Time: 2024-01-14 11:55:40.242
2024-01-14 11:55:40,242 - __main__ - INFO - Python Version: 3.9.18 (main, Jan 11 2024, 11:28:41)

[GCC 12.2.0]
2024-01-14 11:55:40,242 - __main__ - INFO - Frigate Plate Recognizer Version: 1.8.3

2024-01-14 11:55:40,242 - __main__ - INFO - Using CodeProject.AI API
2024-01-14 11:55:40,242 - __main__ - INFO - Starting MQTT client. Connecting to: 192.168.2.20
2024-01-14 11:55:40,243 - __main__ - INFO - MQTT Connected

Nothing is being saved into the plates folder

DrSpaldo commented 6 months ago

@gadget-man how are the plates being stored? are they in folders or just all dumped into the same folder?

I get roughly about 400 per day. So it would end up being a very stacked folder if they are. My log is 7600 lines after 11 days...

If there is nothing in place currently, maybe a folder every month ?

gadget-man commented 6 months ago

Thanks for looking at it @ljmerza and doing the new builds. I am testing it now...

I am getting the following error continually every time a plate is detected:

2024-01-14 11:54:51,040 - __main__ - INFO - Time: 2024-01-14 11:54:51.040
2024-01-14 11:54:51,040 - __main__ - INFO - Python Version: 3.9.18 (main, Jan 11 2024, 11:28:41)

[GCC 12.2.0]
2024-01-14 11:54:51,040 - __main__ - INFO - Frigate Plate Recognizer Version: 1.8.3

2024-01-14 11:54:51,040 - __main__ - INFO - Using CodeProject.AI API
2024-01-14 11:54:51,040 - __main__ - INFO - Starting MQTT client. Connecting to: 192.168.2.20
2024-01-14 11:54:51,041 - __main__ - INFO - MQTT Connected
Traceback (most recent call last):
File "/usr/src/app/./index.py", line 403, in <module>
main()
File "/usr/src/app/./index.py", line 399, in main
run_mqtt_client()
File "/usr/src/app/./index.py", line 358, in run_mqtt_client
mqtt_client.loop_forever()
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 1756, in loop_forever
rc = self._loop(timeout)
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 1164, in _loop
rc = self.loop_read()
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 1556, in loop_read
rc = self._packet_read()
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 2439, in _packet_read
rc = self._packet_handle()
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 3033, in _packet_handle
return self._handle_publish()
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 3327, in _handle_publish
self._handle_on_message(message)
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 3570, in _handle_on_message
on_message(self, self._userdata, message)
File "/usr/src/app/./index.py", line 215, in on_message
snapshot_url = f"{frigate_url}/api/events/{frigate_event}/snapshot.jpg"
UnboundLocalError: local variable 'frigate_event' referenced before assignment
2024-01-14 11:55:40,242 - __main__ - INFO - Time: 2024-01-14 11:55:40.242
2024-01-14 11:55:40,242 - __main__ - INFO - Python Version: 3.9.18 (main, Jan 11 2024, 11:28:41)

[GCC 12.2.0]
2024-01-14 11:55:40,242 - __main__ - INFO - Frigate Plate Recognizer Version: 1.8.3

2024-01-14 11:55:40,242 - __main__ - INFO - Using CodeProject.AI API
2024-01-14 11:55:40,242 - __main__ - INFO - Starting MQTT client. Connecting to: 192.168.2.20
2024-01-14 11:55:40,243 - __main__ - INFO - MQTT Connected

Nothing is being saved into the plates folder

Yep I’m getting the same error. I think it’s because @ljmerza moved quite a bit of code around in the final update.

gadget-man commented 6 months ago

@gadget-man how are the plates being stored? are they in folders or just all dumped into the same folder?

I get roughly about 400 per day. So it would end up being a very stacked folder if they are. My log is 7600 lines after 11 days...

If there is nothing in place currently, maybe a folder every month ?

Currently, it just saves a timestamp file into a single folder. The ability to include the numberplates in the file. Name has also been taken out in 1.8.3. Perhaps it makes sense to add an optional configuration flag, which would create sub folders for individual plates and/or months. If you’re getting a lot of hits, I would recommend setting up a separate script to archive/delete all the files on a periodic basis using crontab. I don’t think this is something that would be best placed being managed within the script itself.

kyle4269 commented 6 months ago

Thanks for looking at it @ljmerza and doing the new builds. I am testing it now...

I am getting the following error continually every time a plate is detected:


2024-01-14 11:54:51,040 - __main__ - INFO - Time: 2024-01-14 11:54:51.040

2024-01-14 11:54:51,040 - __main__ - INFO - Python Version: 3.9.18 (main, Jan 11 2024, 11:28:41)

[GCC 12.2.0]

2024-01-14 11:54:51,040 - __main__ - INFO - Frigate Plate Recognizer Version: 1.8.3

2024-01-14 11:54:51,040 - __main__ - INFO - Using CodeProject.AI API

2024-01-14 11:54:51,040 - __main__ - INFO - Starting MQTT client. Connecting to: 192.168.2.20

2024-01-14 11:54:51,041 - __main__ - INFO - MQTT Connected

Traceback (most recent call last):

File "/usr/src/app/./index.py", line 403, in <module>

main()

File "/usr/src/app/./index.py", line 399, in main

run_mqtt_client()

File "/usr/src/app/./index.py", line 358, in run_mqtt_client

mqtt_client.loop_forever()

File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 1756, in loop_forever

rc = self._loop(timeout)

File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 1164, in _loop

rc = self.loop_read()

File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 1556, in loop_read

rc = self._packet_read()

File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 2439, in _packet_read

rc = self._packet_handle()

File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 3033, in _packet_handle

return self._handle_publish()

File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 3327, in _handle_publish

self._handle_on_message(message)

File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 3570, in _handle_on_message

on_message(self, self._userdata, message)

File "/usr/src/app/./index.py", line 215, in on_message

snapshot_url = f"{frigate_url}/api/events/{frigate_event}/snapshot.jpg"

UnboundLocalError: local variable 'frigate_event' referenced before assignment

2024-01-14 11:55:40,242 - __main__ - INFO - Time: 2024-01-14 11:55:40.242

2024-01-14 11:55:40,242 - __main__ - INFO - Python Version: 3.9.18 (main, Jan 11 2024, 11:28:41)

[GCC 12.2.0]

2024-01-14 11:55:40,242 - __main__ - INFO - Frigate Plate Recognizer Version: 1.8.3

2024-01-14 11:55:40,242 - __main__ - INFO - Using CodeProject.AI API

2024-01-14 11:55:40,242 - __main__ - INFO - Starting MQTT client. Connecting to: 192.168.2.20

2024-01-14 11:55:40,243 - __main__ - INFO - MQTT Connected

Nothing is being saved into the plates folder

Yep I’m getting the same error. I think it’s because @ljmerza moved quite a bit of code around in the final update.

I think frigate_event on 239 needs to be moved up before 215. I'm unable to test right now though.

DrSpaldo commented 6 months ago

Yep I’m getting the same error. I think it’s because @ljmerza moved quite a bit of code around in the final update.

@gadget-man was it working in any of the other versions for you? ie 1.8.2?

Currently, it just saves a timestamp file into a single folder. The ability to include the numberplates in the file. Name has also been taken out in 1.8.3. Perhaps it makes sense to add an optional configuration flag, which would create sub folders for individual plates and/or months. If you’re getting a lot of hits, I would recommend setting up a separate script to archive/delete all the files on a periodic basis using crontab. I don’t think this is something that would be best placed being managed within the script itself.

No worries, no need to make it too complicated then, I can setup a script.

@ljmerza would it be possible to retain the feature @gadget-man added and keep the car registration plate in the file name

gadget-man commented 6 months ago

No I've not managed to get any of the 1.8.x versions working. I've reverted to my forked Repo and am testing a further update.

Once we've got the initial version stabilised using @ljmerza's more eloquent code, I may do a further PR for some enhancements.

ljmerza commented 6 months ago

been writing a ton of tests to avoid this in the future. pushed the latest with those tests and changes

DrSpaldo commented 6 months ago

been writing a ton of tests to avoid this in the future. pushed the latest with those tests and changes

@ljmerza Still getting errors in 1.8.4

2024-01-15 12:10:55,710 - __main__ - INFO - Python Version: 3.9.18 (main, Jan 11 2024, 11:28:41)

[GCC 12.2.0]
2024-01-15 12:10:55,710 - __main__ - INFO - Frigate Plate Recognizer Version: 1.8.4

2024-01-15 12:10:55,711 - __main__ - INFO - Using CodeProject.AI API
2024-01-15 12:10:55,711 - __main__ - INFO - Starting MQTT client. Connecting to: 192.168.2.20
2024-01-15 12:10:55,711 - __main__ - INFO - MQTT Connected
Traceback (most recent call last):
File "/usr/src/app/./index.py", line 433, in <module>
main()
File "/usr/src/app/./index.py", line 429, in main
run_mqtt_client()
File "/usr/src/app/./index.py", line 388, in run_mqtt_client
mqtt_client.loop_forever()
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 1756, in loop_forever
rc = self._loop(timeout)
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 1164, in _loop
rc = self.loop_read()
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 1556, in loop_read
rc = self._packet_read()
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 2439, in _packet_read
rc = self._packet_handle()
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 3033, in _packet_handle
return self._handle_publish()
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 3327, in _handle_publish
self._handle_on_message(message)
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 3570, in _handle_on_message
on_message(self, self._userdata, message)
File "/usr/src/app/./index.py", line 259, in on_message
if check_first_message(message):
TypeError: check_first_message() takes 0 positional arguments but 1 was given
2024-01-15 12:11:07,839 - __main__ - INFO - Time: 2024-01-15 12:11:07.839
DrSpaldo commented 6 months ago

@ljmerza still getting errors in 1.8.7

2024-01-15 16:04:55,493 - __main__ - INFO - Python Version: 3.9.18 (main, Jan 11 2024, 11:28:41)

[GCC 12.2.0]
2024-01-15 16:04:55,493 - __main__ - INFO - Frigate Plate Recognizer Version: 1.8.7

2024-01-15 16:04:55,493 - __main__ - INFO - Using CodeProject.AI API
2024-01-15 16:04:55,493 - __main__ - INFO - Starting MQTT client. Connecting to: 192.168.2.20
2024-01-15 16:04:55,494 - __main__ - INFO - MQTT Connected
Traceback (most recent call last):
File "/usr/src/app/./index.py", line 443, in <module>
main()
File "/usr/src/app/./index.py", line 439, in main
run_mqtt_client()
File "/usr/src/app/./index.py", line 398, in run_mqtt_client
mqtt_client.loop_forever()
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 1756, in loop_forever
rc = self._loop(timeout)
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 1164, in _loop
rc = self.loop_read()
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 1556, in loop_read
rc = self._packet_read()
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 2439, in _packet_read
rc = self._packet_handle()
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 3033, in _packet_handle
return self._handle_publish()
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 3327, in _handle_publish
self._handle_on_message(message)
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 3570, in _handle_on_message
on_message(self, self._userdata, message)
File "/usr/src/app/./index.py", line 341, in on_message
plate_number, plate_score = get_plate(snapshot, after_data, license_plate_attribute)
NameError: name 'license_plate_attribute' is not defined
kyle4269 commented 6 months ago

@ljmerza still getting errors in 1.8.7


2024-01-15 16:04:55,493 - __main__ - INFO - Python Version: 3.9.18 (main, Jan 11 2024, 11:28:41)

[GCC 12.2.0]

2024-01-15 16:04:55,493 - __main__ - INFO - Frigate Plate Recognizer Version: 1.8.7

2024-01-15 16:04:55,493 - __main__ - INFO - Using CodeProject.AI API

2024-01-15 16:04:55,493 - __main__ - INFO - Starting MQTT client. Connecting to: 192.168.2.20

2024-01-15 16:04:55,494 - __main__ - INFO - MQTT Connected

Traceback (most recent call last):

File "/usr/src/app/./index.py", line 443, in <module>

main()

File "/usr/src/app/./index.py", line 439, in main

run_mqtt_client()

File "/usr/src/app/./index.py", line 398, in run_mqtt_client

mqtt_client.loop_forever()

File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 1756, in loop_forever

rc = self._loop(timeout)

File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 1164, in _loop

rc = self.loop_read()

File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 1556, in loop_read

rc = self._packet_read()

File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 2439, in _packet_read

rc = self._packet_handle()

File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 3033, in _packet_handle

return self._handle_publish()

File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 3327, in _handle_publish

self._handle_on_message(message)

File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 3570, in _handle_on_message

on_message(self, self._userdata, message)

File "/usr/src/app/./index.py", line 341, in on_message

plate_number, plate_score = get_plate(snapshot, after_data, license_plate_attribute)

NameError: name 'license_plate_attribute' is not defined

I put in a PR to fix this. I ran a few tests on my camera before the PR and everything seemed to work. Should be good once 1.8.8 is approved.

kyle4269 commented 6 months ago

@DrSpaldo 1.8.8 was just released.

DrSpaldo commented 6 months ago

@DrSpaldo 1.8.8 was just released.

Thanks @kyle4269 . Good news is that I am not getting the errors anymore and it is logging some of the plates.

Bad news is that none of the snapshots are being saved into the folder :(

kyle4269 commented 6 months ago

@DrSpaldo 1.8.8 was just released.

Thanks @kyle4269 . Good news is that I am not getting the errors anymore and it is logging some of the plates.

Bad news is that none of the snapshots are being saved into the folder :(

What's your docker-compose look like? This is what I have

volumes:
  - /cpai/dev/config/plates:/plates:rw

try:

 - /mnt/user/appdata/plate-recognizer/plates:/plates:rw
DrSpaldo commented 6 months ago

What's your docker-compose look like? This is what I have

volumes:
  - /cpai/dev/config/plates:/plates:rw

try:

 - /mnt/user/appdata/plate-recognizer/plates:/plates:rw

That got it working. Thanks @kyle4269

Interesting that the plates folder didn't need the preceding /usr/src/app/ like the config folder did.

For anyone else that encounters the issue that is using Unraid in a stack, here is my config:

services:
  frigate_plate_recognizer:
    image: lmerza/frigate_plate_recognizer:latest
    container_name: frigate_plate_recognizer
    volumes:
      - /mnt/user/appdata/plate-recognizer:/usr/src/app/config
      - /mnt/user/appdata/plate-recognizer/plates:/usr/src/app/plates:rw
      - /mnt/user/appdata/plate-recognizer/plates:/plates:rw
    restart: unless-stopped
    environment:
      - TZ=Australia/Brisbane

There is probably no need to have the plates mapped to two locations, however, I just did it incase.

kyle4269 commented 6 months ago

What's your docker-compose look like? This is what I have


volumes:

  - /cpai/dev/config/plates:/plates:rw

try:


 - /mnt/user/appdata/plate-recognizer/plates:/plates:rw

That got it working. Thanks @kyle4269

Interesting that the plates folder didn't need the preceding /usr/src/app/ like the config folder did.

For anyone else that encounters the issue that is using Unraid in a stack, here is my config:


services:

  frigate_plate_recognizer:

    image: lmerza/frigate_plate_recognizer:latest

    container_name: frigate_plate_recognizer

    volumes:

      - /mnt/user/appdata/plate-recognizer:/usr/src/app/config

      - /mnt/user/appdata/plate-recognizer/plates:/usr/src/app/plates:rw

      - /mnt/user/appdata/plate-recognizer/plates:/plates:rw

    restart: unless-stopped

    environment:

      - TZ=Australia/Brisbane

There is probably no need to have the plates mapped to two locations, however, I just did it incase.

Yeah, I couldn't get the plates to save either.. So I changed a piece of code to look at that location. Glad it's working for you!

EDIT: I've been using an older version and only need to use /config and /plates. So, I wanted to figure out why I now have to use /usr/src/app instead of /plates or /config. In the new Dockerfile, I see "WORKDIR /usr/src/app" whereas I don't have that in my version. If I remove the period in CONFIG_PATH, DB_PATH, LOG_FILE and SNAPSHOT_PATH I don't have to use /usr/src/app. Not sure what the correct way is. @ljmerza

DrSpaldo commented 6 months ago

For reference, I wanted to have the files moved into a monthly folder, as I will get 200+ per day. So a friend helped me write a script, see below if anyone else wants to use it...

#!/usr/bin/env bash

# Comment out to actually do stuff
#DUMMY=echo

set -e

if [ -z "$1" ]; then
    echo "Must pass directory name to process as first argument"
    exit 1
fi
if [ -z "$2" ]; then
    echo "Must pass destination directory name as second argument"
    exit 1
fi

find "$1" -maxdepth 1 -type f -iname \*.png | ( while [ 1 ]; do
    read fname
    if [ $? -ne 0 ]; then
        break
    fi
    if [ -z "$fname" ]; then
        continue
    fi
    # Get modification time of file as epoch timestamp
    tstamp=$(stat -c %Y "$fname")
    # Create destination directory name using timestamp
    dirname="$2/$(date -d @$tstamp +%Y/%m)"
    if [ ! -e "$dirname" ]; then
        $DUMMY mkdir -p "$dirname"
        if [ $? -ne 0 ]; then
            echo "Unable to create $dirname, aborting"
            exit 1
        fi
    fi
    $DUMMY mv "$fname" "$dirname"
    if [ $? -ne 0 ]; then
        echo "Unable to move $fname to $dirname, aborting"
        exit 1
    fi
done )
gadget-man commented 6 months ago

Same issue here on the config. On a synology system, it now seems to be inconsistent between how the config folder is mapped in docker-compose.yml and how you need to map the plates directory, which is somewhat confusing.

I think the issue is because in index.py, the CONFIG_PATH is a relative path i.e.: ./config/config.yml, whereas SNAPSHOT_PATH has been changed to absolute: /plates

gadget-man commented 6 months ago

I've also noticed that neither draw_box nor always_save_snapshot are working as expected. For draw box, I think it's because the code now only saves a snapshot of the cropped image (rather than the full snapshot), so the box is probably being drawn outside the frame of the snapshot. I can't easily see why always_save_snapshot isn't working as expected.

kyle4269 commented 6 months ago

I've also noticed that neither draw_box nor always_save_snapshot are working as expected. For draw box, I think it's because the code now only saves a snapshot of the cropped image (rather than the full snapshot), so the box is probably being drawn outside the frame of the snapshot. I can't easily see why always_save_snapshot isn't working as expected.

I'm pretty sure if line 222 crop is set to 0 it'll no longer crop the image.

I've ran into the same issue with the box being drawn outside the frame of the snapshot. If you compare the snapshot that's saved to the one frigate has under events. You'll see they're different.

I've talked to Nick about this a few times. He suggested a couple things. Wait about 5 seconds for the event to end, then saving the snapshot. I currently do this and my snapshot will be the exact same as frigate. But the box is still drawn outside the frame.

Watch for the events "end_time" and save the snapshot then.

For me, I'm just grabbing plates from my driveway, so waiting 5 seconds works for me. BUT those who are getting plates from the road, that probably wouldn't be a good route.

So what I ended up doing was waiting 5 seconds and editing the image with the plate number under the date and time. It then sends it to my telegram.

gadget-man commented 6 months ago

I think the issue is that frigate returns the dimensions of the plate based on the full sized snapshot, which we are then applying to the bottom corner of the cropped image. I agree, setting crop=0 should solve this, but not sure how much that affects the efficiency of plate_recognizer? I think this is compounded by the fact that frigate may update the snapshot image for the event several times, so they are slightly out of sync - not sure there's anything that can be done about that.

I've also started noticing a new issue that I hadn't come across - I'm frequently seeing a duplicated snapshot from Frigate as top_score from before and after are the same appearing several times, including the very first mqtt entry, which results in the entire event being missed from detection. Anyone else seeing the same? I don't recall coming across this in v 1.7.X versions. I think this is happening when the top_score for an event is prior to the object entering a zone being monitored by frigate_plate_recognizer. Let me know if I need to raise this as a separate issue?

ljmerza commented 6 months ago

could we retrieve the image again but with crop=0 just for the image save? I cant easily test this since cars dont pass by my cameras too often hence the need for the automated tests

gadget-man commented 6 months ago

could we retrieve the image again but with crop=0 just for the image save? I cant easily test this since cars dont pass by my cameras too often hence the need for the automated tests

That's what I did in the original PR - for save_image it retrieved a new copy of the snapshot and applied the box to that. However, I don't think that would solve the issue of the 'box' dimensions in the matt being different from the snapshot, because there could be a few 100ms delay between the script processing the mqtt message and requesting the snapshot from frigate, by which time Frigate may have updated the snapshot (and a later mqtt message would therefore have more updated box coordinates). I wonder if there's a way to interrogate Frigate to get the box dimensions for an specific event - in which case you could do it based on the delay concept (or wait until the event has an end time)

ljmerza commented 6 months ago

Yes the delay workaround was brought up before but wasn't a very clean fix since if any event lasted longer it would not work. Ideally there's some indication when an event has ended and we'd use that to wait to get the image

gadget-man commented 6 months ago

I think we might be able to overcome this by calling the api/events call to retrieve updated data, rather than using the data from the after payload. I'll have a play with this. If so, it would make sense to move the save_image function back to the end of the script (after posting to mqtt) so that this provess doesn't delay the overall mqtt updates.

kyle4269 commented 6 months ago

Once "end_time" is populated with a time. The event is officially over and stored into frigates db. Any thoughts on that?

gadget-man commented 6 months ago

Once "end_time" is populated with a time. The event is officially over and stored into frigates db. Any thoughts on that?

In the vast majority of situations I think this would work, however if a vehicle arrives in frame and then parks, the event would stay 'live'. What we really want is just to grab a snapshot and it's associated event details at the same time. I think the best way to do this is to call a new response.get for a full snapshot and then an api call to get the event details immediately afterwards (or before) and then use that data. It is likely that the snapshot would be a slightly different Frame from that used by plate_recognizer to detect the plate, but at least the box would align....

kyle4269 commented 6 months ago

Here is an example.

Waiting 5 seconds: image

Not waiting: image

kyle4269 commented 6 months ago

Yes the delay workaround was brought up before but wasn't a very clean fix since if any event lasted longer it would not work. Ideally there's some indication when an event has ended and we'd use that to wait to get the image

I was driving up and down my driveway testing it myself.. Until I found out you can manually run clips through Frigate.. I copied all the settings from my LPR config to my "test" see below.. Makes testing so much easier.

https://docs.frigate.video/development/contributing/#2-modify-your-local-config-file-for-testing

cameras:
   test:
     ffmpeg:
        inputs:
          - path: /media/frigate/testing/TundraFrontDay.mp4
            input_args: -re -stream_loop -1 -fflags +genpts
gadget-man commented 6 months ago

I'm looking at the alternative strategy where we grab a new (uncrossed) snapshot, as well as the event data using GET /api/events/<id>. However, I've noticed that unlike the mqtt event data, the box coordinates returned in the API call are all decimals (e.g. [0.28828125, 0.42916666666666664, 0.14140625, 0.08194444444444444]). I can't find a way to translate those co-ordinates into sensible numbers relative to the image size to draw a box. I've compared them against the currently returned coordinates that we're using to draw the box in save_image and can't see any correlation. Anybody know how we turn these co-ordinates into something appropriate to then draw a box using them?

kyle4269 commented 6 months ago

@gadget-man Looks at the way Nick does it https://github.com/blakeblackshear/frigate/discussions/8165 It looks like he gets the even data the same way you're trying. He also does a calculation to find the coordinates for the image. I believe he's finding the coordinates of the license plate then sending that cropped image to CPAI. Maybe this will help?

# find coordinates of image to send to detector
x_mid = (box[0] + (box[2] / 2)) * known_res[0]
y_max = (box[1] + box[3]) * known_res[1]

cropped_image = img.crop((max(0, x_mid - 150), 0, min(known_res[0], x_mid + 150), known_res[1]))

Edit: Here's an explanation from Nick..

In the DB they are stored in relative x, relative y, relative width, relative height.

The box is sent directly in mqtt and then converted to relative coordinates before being saved into the db

"the box coordinates would be box[0] * width, box[1] * height, (box[0] + box[2]) * width, (box[1] + box[3]) * height"