Skip to content

zizumara/LPRCam

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

48 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LPRCam

Installed Camera

(2022-06-06 NOTE: UCTronics has modified the design of the Arducam 12.3 MP HQ camera with automatic IR-cut filter. The new design requires the Bullseye O/S to be used, and the IR-cut filter interface now works differently. Unfortunately, there isn't a distribution of openalpr for Bullseye. You may be able to special order the older version of the camera from Arducam and continue to use Buster. If anyone can figure out how to get this project updated for Bullseye, I'd like to hear from them.)

This project includes the software and hardware design for a DIY motion-activated Raspberry Pi security camera. The Linux Motion application is used to detect motion and capture images. The following hardware is used for this project:

  • Raspberry Pi Zero W running Buster O/S
  • Pi Zero W 6" camera ribbon cable (Amazon)
  • Raspberry Pi 4 (for web server)
  • Arducam 12.3 MP HQ camera with automatic IR-cut filter (www.arducam.com) -- photocell removed
  • Arducam 12mm CS-Mount Lens with Manual Focus and Adjustable Aperture (Amazon)
  • A custom IR illuminator (KiCAD files included)
  • A custom ambient light sensor (KiCAD files included)
  • A 3D-printable enclosure (STL files included) -- use white PETG filament
  • A 5V 2.5A step-down voltage regulator (Pololu #2858)
  • 2.1mm DC panel mount barrel jack (Adafruit #610) and plug
  • CESFONJER Mini Locking Toggle Switch (Amazon)
  • GIVERARE Combination Travel Cable Lock (Amazon)
  • DEWENWILS 60W Outdoor Low Voltage Transformer (Amazon)
  • Woods 55213143 16/2 Low Voltage Lighting Cable, 100-Feet (Amazon)
  • Red and green LEDs with 330 Ohm current limiting resistors
  • 26 AWG wiring with various Dupont connectors (KiCAD files included)
  • Clear Lexan sheet 0.08x7.6x11 inch or similar dimensions (Amazon)
  • Clear silicone waterproof sealant (Amazon)
  • Silicone modified conformal coating (Amazon)
  • 22 #3-48x1/2" steel screws (Fastenal or McMaster-Carr)
  • 12 #3-48x1/16" steel screws (Fastenal or McMaster-Carr)
  • Microchip Pickit 4 programmer (for programming the custom light sensor)
  • (Optional) Wireless Access Point (Amazon)

For nighttime operation, when the ambient light sensor registers light below a configured level, software enables the IR illuminator and switches in the IR-cut filter on the camera module. The light level is used to select one of three different Motion configuration files which have mmalcam_control_params settings appropriate for daytime, twilight, and nighttime operation, respectively. The light level is a time-averaged reading for which the width of the sampling window may be adjusted via the sensor I2C interface.

The camera box should be printed with white PETG filament to resist outdoor heat as well as heat generated by the IR illuminator and Pi Zero W. All parts of the box should be given four coats of silicone modified conformal coating, both inside and out. (WARNING: silicone modified conformal coating must be applied in an area with good ventilation.) The Lexan covers for the camera shroud and IR array opening must be cut to fit from the Lexan sheet. All seams must be filled with silicone sealant to produce a waterproof enclosure, including around the power jack.

Camera Box Interior

Web Server

The files included in the /web directory provide everything needed to create a web server for reviewing captured images and license plate numbers. The web server runs on a separate Raspberry Pi 4B. If the web server is to be accessible from the Internet, it is strongly recommended that the security hardening procedures be followed in setup.txt.

During operation, captured files are periodically copied from the Pi Zero W to the web server via rsync. A wireless access point may be needed if the camera box is not close to your wireless router. The web server performs the CPU-intensive analysis of the captured images using OpenALPR to detect and read license plates. The results are displayed on the web page, an example of which is shown below (for security reasons, plate numbers and actual camera location are blanked out in grey).

Web Page

For each captured image, a thumbnail is displayed with the date and time of capture and the lighting level at the bottom in format s###, where s is 'd' for day, 't' for day-twilight, 'u' for night-twilight, and 'n' for night, and the 3-digit number represents the value read from the light sensor. If a plate is detected by OpenALPR, the highest confidence plate number result is displayed below the capture date, along with the best confidence level of the optical character recognition (OCR) algorithm (0-100%). A question mark (?) follows the plate number as a signal that this is the best guess by OpenALPR. Users may click on any thumbnail to display the full resolution image on a new page. On this page, the user may enter the actual license plate number so that it may be displayed on the main page in green followed by the text "** verified **".

The top of the main page has a filter section which may be used to limit the number of images displayed.

  • Starting date: By default, all captured images are displayed regardless of capture date. Setting the date and clicking Apply Filters can be used to limit the list to more recent images.
  • Search for license: Enter license plate text in this box and click Apply Filters to find OpenALPR results similar to the text supplied. Use the match strength radio buttons to set how close the match must be to the supplied text.
  • Show only detected plates: Check this box and click Apply Filters to display only images for which OpenALPR has found a license plate.

The license plate search algorithm is optimized using OCR statistics gathered from hundreds of prior OpenALPR results that were each manually verified on the view full image page. Entries made here are added to the OpenALPR .json files in the results directory. Certain characters like 'B' may be misinterpreted by the OCR engine as '8', or 'D' may be misinterpreted as '4'. Some characters, like 'I' may not be present at all on any license plate, but might be misidentified from a '1' or from an edge on the license plate. The genalprstats.py module analyzes the contents of the results directory to determine the frequency at which characters are correctly or incorrectly identified. The results of this analysis are stored in ocrstats.pickle and applied when the user performs a license plate search using a modified Wagner-Fischer algorithm to find the Levenshtein distance between the plate number entered and the plate numbers returned by OpenALPR.

The Levenshtein distance is defined as the smallest number of 1-character substitutions to convert one string into another. The modifications to the Wagner-Fischer algorithm allow for the substitution value (normally 1) to be less than one depending on the frequency at which the OCR engine makes an error for the particular substitution. This modified Levenshtein distance can be set as the threshold to count an OpenALPR result as as match when performing a search. The threshold for the search can be set using the radio buttons at the top of the main web page. A modified Levenshtein distance of 3.0 or greater signifies a "weak" match, while a modified Levenshtein distance of 1.0 or less represents a "stong" match.

The ocrstats.pickle file in this archive are specific to the location at which testing was originally performed. This may not be suitable for a different location, in which case a new file might be generated. However, keep in mind that this requires a large number of plates to be manually verified to generate sufficient data for the analysis. The existing ocrstats.pickle file was generated from approximately 1,000 analyzed plates, and a similar number is recommended for a new analysis.

Performance

The following factors are the most significant in their effect on the performance of this system.

  • Motion frame rate: The Motion application can capture about 1 to 2 frames per second under the given configuration. This depends on image size and the processing power of the Raspberry Pi Zero W. The current frame rate appears to be suitable for capturing at least one image of a license plate on a moving vehicle under most conditions. The frame rate could be increased by reducing the image size or replacing the Pi Zero W with a Pi Zero 2 W. However, increasing the rate at which images are captured may be detrimental to other performance factors.
  • Image capture rate: The Motion application may experience false positives for detecting motion due to changing lighting conditions. In particular, windy, partly cloudy days often produce hundreds or even thousands of additional images per day, as the changing cloud shadows often cause significant numbers of pixels in the image to change intensity. The threshold parameter in motion_day.conf sets the number of changed pixels to trigger motion capture.
  • Image transfer rate: Images are periodically transferred from the camera system to the web server for OpenALPR analysis using rsync. If the image capture rate is large for an extended period, this can generate a large backlog of images to transfer, depending on the configured number of days to keep images in LPRCam.conf. The result may be that the web server gets behind by several hours in analyzing images. To reduce the number of image files to be synchronized, keep the number of days to keep files in LPRCam.conf low (no more than 1.0 days). Note that the web server will keep images for three days, which is hardcoded in LPRserver.py. The rsync bwlimit parameter is also hardcoded in LPRserver.py at 400 kbps to avoid overloading the wireless network, but may be increased or eliminated.
  • ALPR masks: A portion of each image may be excluded from analysis by the OpenALPR application to reduce processing time for each image as defined by mask files. Two mask files are provided in this archive, alpr-mask-1600x960.jpg and alpr-mask-800x480.jpg, which mask out the lower portion of the image where license plates are not expected to be found. It may be necessary to replace or exclude these files. Note that if renamed or excluded, the configuration files openalpr.defaults.1600x960 and openalpr.defaults.800x480 must be updated.
  • ALPR processing: OpenALPR consumes considerable CPU resources in analyzing each image, which can result in a significant processing backlog. Performance can be improved by reducing image dimensions. Note that this must be done for all the motion configuration files and the OpenALPR mask files.

About

DIY automated license plate reader camera and web server

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages