1
$\begingroup$

I'm studyng stereo cameras, and I want to build one. I searched a lot in internet, and the opinions are quite different about this topic.

Basically, my question is:

Can I synchronize two usb cameras triggering them together, shooting at the same instant?

My answer (99% wrong) is:

Yes, with a multithread architecture and a parallel program, can I have two streams at the same instant.

but it seems too easy, and will never work.

  1. Why?
  2. what difference should I expect between the two images? (in millisecond I mean)
  3. Is there a solution in order to have a real global shutter? (without buy another cameras)
  4. I also see some solution for triggering one camera using Arduino. Could be extended to 2 cameras systems?

Hope these are not to many questions. Thanks PS: books suggestion or papers are appreciated

$\endgroup$
  • $\begingroup$ how are the two cameras triggered? .... can they have a hardware trigger? $\endgroup$ – jsotola Sep 29 '18 at 6:06
  • $\begingroup$ at the moment are not triggered, are two simple usb cameras and I just acquire image with opencv. I want to understand if usb cameras can have an hardware trigger, and if yes how to build one $\endgroup$ – Giuseppe Sensolini Sep 29 '18 at 11:23
  • $\begingroup$ I have taken stereo images using only 1 camera. (Forrest scene, nothing moved). So it comes down to specifying your needs. If @sdfgeoff answer is good enough then accept it. Otherwise you should reword your question to make it clear what you need. $\endgroup$ – st2000 Nov 4 '18 at 13:40
1
$\begingroup$

As you say, you can't trigger them at the exact same time without hardware capable of doing so. Some IMU's supply an external trigger pin, and I see no reason why you couldn't buy cameras that have a trigger pin.

Sure, your suggestion of using two threads and triggering them both at the same time that way would work, so long as you can send messages to both threads at the same time. Unfortunately, you cannot send messages to two threads at the exact same time, and you cannot ensure the processor is running those threads (the OS has thousands of threads it has to run) so you'll have to settle for a very small time difference between them. You'll also end up with all the normal multi-thread communication issues.....

Fortunately, there is a simpler solution. OpenCV provides multiple different ways to get images from a camera. The normal one is to use the function read(). This function actually does multiple things. First it tells the camera to start taking a photo. Then it waits until the camera has taken the photo, and finally, it reads the photo back. This whole process takes multiple milliseconds (on a 30FPS camera it takes ~32ms, on a 60FPS camera it takes ~17ms). You can drastically reduce this time by using the functions grab() and retrieve(). Grab tells the camera to take the photo, and retrieve waits for the camera and gets the data. So if you do (pseudo-code):

cam1.grab()  # very fast
cam2.grab()  # also very fast

img1 = cam1.retrieve()  # slow because it has to wait for the camera
img2 = cam2.retrieve()  # fast because when cam1 has finished, cam2 probably has as well

Using this method you can retrieve the images from both cameras at the framerate of the cameras. This method is mentioned briefly in the opencv documentation where it says:

The primary use of the function [note: the grab() function] is in multi-camera environments, especially when the cameras do not have hardware synchronization. That is, you call VideoCapture::grab() for each camera and after that call the slower method VideoCapture::retrieve() to decode and get frame from each camera. This way the overhead on demosaicing or motion jpeg decompression etc. is eliminated and the retrieved frames from different cameras will be closer in time

$\endgroup$
  • $\begingroup$ Thanks! I'll try this method, 32ms it's a lot but for many application should work. However I'll buy a Kinect v2, and compare the results $\endgroup$ – Giuseppe Sensolini Oct 11 '18 at 22:11
  • $\begingroup$ You should be able to get less than 32ms by using separate grab and recieve functions $\endgroup$ – sdfgeoff Oct 23 '18 at 8:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.