Taking images in parallel and saving them asynchronously using Python

Viewed 655

This is a more general question regarding concurrency/parallelism, but as I don't have too much experience in those topics I am asking specifically for my use case.

I have two cameras plugged into my PC. I can control them over an SDK (PySpin in my case). I acquire and save the images for duration seconds using this simplified loop:

count = 0
t_end = time.time() + duration
while time.time() < t_end:
    for cam in cameras:
        img_raw = cam.GetNextImage()
        img = img_raw.GetNDArray()
        cv2.imwrite('{}_img_{}.png'.format(device_name, count), img)
        img_raw.Release()
        count += 0

There are two problems here:

  1. The cameras block each other. Let's say the first camera has a high exposure time. The other cameras would need to wait for this camera to take the image.
  2. Saving the images is slowing down the process and could theoretically slow down the frame rate of the cameras.

I would like to do following: The cameras should take the images in parallel and images should be saved in whenever an image is taken, i.e. while the camera is already acquiring the next image.

As I said, I am not familiar with concurrency/parallelism and therefore I don't really know how to tackle it. But, I think to solve the first problem I need multi processing/threading (parallelism) for example using multiprocessing. But for the second problem I would need an asynchronous process using asyncio.

Am I on the right path? If so, how could I implement this?

2 Answers

Very generic advice without any code but it might be worth a try:

suggestion to implement three threads

Thread 1: captures raw images from camera 1 and adds a tuple of (raw_image, filename_to_save_as) to a thread safe queue (from queue import Queue)

Thread 2: captures raw images from camera 2 and adds a tuple of (raw_image, filename_to_save_as) to a thread safe queue (from queue import Queue)

Thread 3: processes the queue and saves each raw image under the passed filename.

Please note: You might want to add a max size to the queue to avoid memory overflows in case wrting the files is really the bottle neck in your setup

I might be late to this, but I'm developing a Python package that lets you do just this. It's still very much under development, but check it out if you're interested:

https://github.com/jbhunt/parallel-pyspin

The TLDR is each camera runs on it's own process (via multiprocessing). There are classes which handle all of the nittty gritty of setting up a primary and secondary cameras. All you need to know are the cameras' serial numbers plus you have to follow these instructions for setting up the physical trigger:

https://www.flir.com/support-center/iis/machine-vision/application-note/configuring-synchronized-capture-with-multiple-cameras

Feel free to contribute :)

Related