Abstract
Now that camera is capturing (manually) photos of high-speed cars - we need to trigger image capture and transfer to RPi automatically. This enables streaming of images from DSLR to RPi, and then makes those images available for post-processing in subsequent steps.
ToC (Step-by-Step)
- Overview: OpenCV in Python for End-to-end License Plate Detection.
- Camera and computer setup. Raspberry pi (RPi), Canon DSLR, f-stop and ISO.
- Capturing images from DSLR to RPi. Automating capture of images and transfer to RPi.
- Model for detecting cars. Train model from scratch using YOLO and labeled images.
- Crop bounding box + rotate.
- TBD -- Model for finding license plates. Train a second model with YOLO.
- TBD -- Crop bounding box.
- TBD -- Read license plate with OCR. Pre-process image, and extract text with Paddle OCR.
Recipe
At this point we should have camera mounted, connected to RPi, and capturing nicely focused images (manually) of cars and license plates.
Now that we have manual capture working, we will write code to control DSLR from RPi. We will capture image, transfer to RPi, and repeat.
-
Capture image - borrows heavily from https://thezanshow.com/electronics-tutorials/raspberry-pi/tutorial-41
- Use gphoto2 library to communicate with DSLR over USB from RPi. The following code uses basic “--capture-image-and-download” command to capture, transfer, and repeat.
- The kill gphoto2 pid is an unfortunate RPi thing, where the OS auto-mounts the DSLR as a drive on USB connection. Thus for gphoto2 to issue capture command, we need to kill pid first. It’s weird, but it is a thing.
from sh import gphoto2 as gp import signal, os, subprocess import re # kill the gphoto process from turning on the camera or rebooting the RPi def killGphoto2Process(): p = subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE) out, err = p.communicate() # search for the process we want to kill for line in out.splitlines(): if b'gvfsd-gphoto2' in line: # kill that process! pid = int(line.split(None,1)[0]) os.kill(pid, signal.SIGKILL) def captureImages(): captureFilenameRegex = '(CANON\/(.+JPG))' ret = gp(captureCommand) captureFilename = re.search(captureFilenameRegex, str(ret)) if len(captureFilename.groups()) < 2: print("did not regex-extract filename. exiting") quit() return captureFilename.group(2) ########################################################################## # begin main captureCommand = ['--capture-image-and-download'] saveLocation = '/home/pi/Projects/TakePhoto1/photos/temp capture/' # actually operate camera killGphoto2Process() os.chdir(saveLocation) while True: captureFilename = captureImages() print(captureFilename)
Repeat
Capture, transfer, repeat - automatically from DSLR to RPi.
Now we have DSLR zoomed in on highway, capable of capturing high-speed car with detail, RPi is driving capture and transferring photos to storage. Next up is honing in on license plates per photo by detecting cars in each image.
Next Link: Model for detecting cars
Appendix: References
- https://thezanshow.com/electronics-tutorials/raspberry-pi/tutorial-41
- http://www.gphoto.org/doc/remote/
- More on the need for kill gphoto2 pid https://forums.raspberrypi.com/viewtopic.php?t=202934
Appendix: Interesting Points
- Learned through practice that light conditions influence heavily successful capture of images. This rig doesn’t work at night (not yet?) I suspect this is why highway toll cameras are set up in arrays like this - closer to highway surface, and without perspective eschew.
- For anyone concerned, taking photos in public (eg of license plates) are not restricted legally. https://www.google.com/search?q=photos+in+public and https://www.acludc.org/en/know-your-rights/if-stopped-photographing-public
Top comments (0)