DEV Community

Jeremy
Jeremy

Posted on • Edited on

Capturing Images from DSLR to RPi

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)

License plate detection workflow visualized

  1. Overview: OpenCV in Python for End-to-end License Plate Detection.
  2. Camera and computer setup. Raspberry pi (RPi), Canon DSLR, f-stop and ISO.
  3. Capturing images from DSLR to RPi. Automating capture of images and transfer to RPi.
  4. Model for detecting cars. Train model from scratch using YOLO and labeled images.
  5. Crop bounding box + rotate.
  6. TBD -- Model for finding license plates. Train a second model with YOLO.
  7. TBD -- Crop bounding box.
  8. 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.

  1. 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)
    
  2. Transfer image
    Single image captured from DSLR
    Capture one automatically to RPi

  3. Repeat
    Loop images captured from DSLR
    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

Appendix: Interesting Points

Top comments (0)