TL;DR — You can now configure ALPR in the Event Server. It usually works pretty well, as long as you can configure your zones correctly to grab alarmed images that have the license plate. See this.
(Updated Jul 12, 2019. OpenALPR support also added, thanks to Andrew B)
I have been thinking about adding license plate detection to ZM for a while. There was some work done several years ago on this front which used openALPR. However, I found openALPR too inaccurate to use. I had actually integrated openALPR to my Event Server several months ago, but never released it, because it never got a single plate right (even after calibration) from my camera view. My camera view is at an elevation (most folks who use ZM have cameras at an elevation, based on what I see)
In general, when Open ALPR was first made, it was quite cutting edge, but now, with the advent of CNNs, Attention Networks et. al, the reliance of complex rules for plate recognition have changed. In fact, today, if I were to do this myself, I’d do it the following way:
- Train YOLOv3 to detect a license plate. This would involve getting large data sets of vehicles at all angles/elevations, marking boxes around license plates and training that network.
- Given a detected plate, use some form of an attention network to bring out the text
While there are many license plate databases available in the wild, thinking about it and doing it are two entirely different things.
Isaac Connor recently pointed me to the folks at Plate Recognizer. They’ve done the hard work of training their own models and offer a cloud API which as of July 2019, offers a generous 2500 free API calls per month.
First, here is a comparative:
OpenALPR, to the best of my knowledge doesn’t use DNNs while Plate Recognizer does, so it’s not surprising.
That being said, OpenALPR does provide a lot more information when it does find a plate, including car model, make, year of manufacture and whole lot more.
So I decided to integrate Plate Recognizer into the Event Sever as a machine learning hook. I’d like to also add it to zmMagik, but I’m pretty sure I’ll exceed their API limit. Maybe some other day. Or maybe some of you would like to sign up to a paid plan and give me access — then I’ll integrate it with zmMagik too :). I’ll be honest though, Plate Recognizer’s pricing is very competitive. If I had a business that needs high quality ALPR I’d happily buy their plans. But I don’t. I’m doing this for fun.
I am told plate recognition is a big ask for many ZoneMinder users, so I hope you like it. And hopefully some of you buy their plans and help them succeed.
How to use it
Really very simple. They offer two models:
- A cloud API version if you have internet
- A locally hosted docker image if you don’t have internet (you’ll still need internet once in a while for them to check licenses). Very cool to have both models and done so easily
I integrated both.
objectconfig.ini you will see:
# currently unused
# replace with your api key
# leave this as yes for now
# if yes, then it will log usage statistics of the ALPR service
# If you want to specify regions. See http://docs.platerecognizer.com/#regions-supported
# If you want to host a local SDK https://app.platerecognizer.com/sdk/
#alpr_url=https://localhost:8080# minimal confidence for actually detecting a plate
# minimal conficende for the translated text
Read the comments — its pretty self explanatory.
To reduce the number of API calls, I first use YOLO to detect vehicles. If YOLO detects a vehicle, the I invoke the plate recognition API. So to get this to work, use this for the monitor that needs ALPR:
models = yolo,alpr,face # obviously, face is optional
As long as you have YOLO before alpr and YOLO is run, it will invoke ALPR if it finds a vehicle. Obviously, if you have:
Then if it finds a face, it won’t invoke yolo and will not invoke alpr. So use
detection_mode=all if you have multiple models, or put
Also, don’t just blindly enable alpr for all your monitors. Only enable it for the monitor where you need to read plates.
Maximizing changes of getting a license plate
Given the Event Server only has a total of 2 frames in which the license plate should show up (snapshot or alarm, or a custom fid), you’ll need to get intelligent with your zones. Here are my driveway zones.
For cars backing out of my garage, as long as the car is part of the preclusive zone, alarms won’t trigger (even if its in the active zone). Once a car is out of the preclusive zone and inside the active zone, the alarm will trigger. This would mean the front of the car is visible and therefore the license plate.
For cars coming into my driveway (primary usecase), it will first hit the active zone. Note that I’ve put it deep inside my driveway because cars turn in, and I’d like it as straight as possible.
Your use-case may be different. Get creative. Have fun.