title: Using OpenCV, Boost threading and multiple cameras
body: <p>I am trying to write a program that is able to capture images from two different cameras in two different threads. I want to do this because when I do this in the same thread I have to keep waiting for cvQueryFrame twice the amount of time and so i can not grab images at 30 fps (I get 15 FPS from each camera). </p>
  
  <p>I have taken a look at this SO post, but this only works for one camera. <a href="https://stackoverflow.com/questions/9364241/using-cvqueryframe-and-boostthread-together">Using cvQueryFrame and boost::thread together</a></p>
  
  <p>My current program gives varying results, sometimes it gives memory leaks, usually I just don't see anything happening and sometimes it worls for a few seconds but the the image freezes again. The strange thing is that earlier when I didn't call cvShowImage, but had my imageProcessing function do something useful I could see that I was getting real time results from both cameras. I assume this means that it is possible to make this work, but that I made a stupid mistake somewhere. My OS is LINUX and I am using OpenCV 2.4</p>
  
  <p>My code:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;cstdio&gt;
  #include &lt;cv.h&gt;
  #include &lt;ml.h&gt;
  #include &lt;cvaux.h&gt;
  #include &lt;highgui.h&gt;
  #include &lt;vector&gt;
  #include &lt;stdio.h&gt;
  #include "producer_consumer_queue.hpp"
  
  
  
  //Camera settings
  int cameraWidth = 1280;
  int cameraHeight = 720;
  int waitKeyValue = 5;
  bool threads_should_exit = false;
  
  CvCapture * capture;
  CvCapture * capture2;
  
  using namespace std;
  using namespace cv;
  
  void grabFrame(concurrent_queue&lt;IplImage* &gt; * frame_queue, int camNumber) {
      try {
          //Load first frames
          cout &lt;&lt; "grabFrame: " &lt;&lt; camNumber &lt;&lt; " init with " &lt;&lt; cameraWidth &lt;&lt; " x " &lt;&lt; cameraHeight &lt;&lt; endl;
  
          IplImage* frame;
          if (camNumber == 0)frame = cvQueryFrame(capture);
          if (camNumber == 1)frame = cvQueryFrame(capture2);
          while (frame &amp;&amp; !threads_should_exit) {
              if (camNumber == 0)frame = cvQueryFrame(capture);
              if (camNumber == 1)frame = cvQueryFrame(capture2);
              IplImage* frame_copy = NULL;
              frame_copy = cvCloneImage(frame);
  
              if (camNumber == 0)cvShowImage("NE", frame);
              cout &lt;&lt; "grabFrame: " &lt;&lt; camNumber &lt;&lt; " pushing back to queue" &lt;&lt; endl;
              frame_queue-&gt;push(frame_copy);
  
              int k = cvWaitKey(waitKeyValue);
  
              if (k == 1048603 || k == 27 || k == '\r') {
  
                  cout &lt;&lt; "grabFrame: Process killed" &lt;&lt; endl;
                  //release memory
                  threads_should_exit = true;
              }
  
          }
      } catch (const concurrent_queue&lt;IplImage* &gt;::Canceled &amp; e) {
          cout &lt;&lt; "grabFrame: Show thread is canceled" &lt;&lt; endl;
          return;
      }
  
  }
  
  void processFrames(concurrent_queue&lt;IplImage* &gt; * frame_queue0, concurrent_queue&lt;IplImage* &gt; * frame_queue1) {
      try {
          do {
              cout &lt;&lt; "processFrames: Processing two frames" &lt;&lt; endl;
              IplImage* frm = NULL;
              frame_queue0-&gt;wait_and_pop(frm);
              IplImage * frm2 = NULL;
              frame_queue1-&gt;wait_and_pop(frm2);
              cvReleaseImage(&amp;frm);
              cvReleaseImage(&amp;frm2);
          } while (!threads_should_exit);
      } catch (const concurrent_queue&lt;IplImage* &gt;::Canceled &amp; e) {
          cout &lt;&lt; "processFrames: Processing thread is canceled" &lt;&lt; endl;
          return;
      }
  }
  
  int main() {
      capture = cvCreateCameraCapture(0);
      capture2 = cvCreateCameraCapture(1);
      cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, cameraWidth);
      cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, cameraHeight);
      cvSetCaptureProperty(capture2, CV_CAP_PROP_FRAME_WIDTH, cameraWidth);
      cvSetCaptureProperty(capture2, CV_CAP_PROP_FRAME_HEIGHT, cameraHeight);
  
      boost::thread_group frame_workers;
      boost::thread_group frame_workers2;
      concurrent_queue&lt;IplImage* &gt; frame_queue(&amp;frame_workers);
      concurrent_queue&lt;IplImage* &gt; frame_queue2(&amp;frame_workers2);
  
      boost::thread * query_thread = new boost::thread(processFrames, &amp;frame_queue, &amp;frame_queue2);
      boost::thread * cam0_thread = new boost::thread(grabFrame, &amp;frame_queue, 0);
      usleep(10000);
      boost::thread * cam1_thread = new boost::thread(grabFrame, &amp;frame_queue2, 1);
  
      frame_workers.add_thread(query_thread);
      frame_workers.add_thread(cam0_thread);
  
      frame_workers2.add_thread(query_thread);
      frame_workers2.add_thread(cam1_thread);
      while (true) {
          if (threads_should_exit) {
              cout &lt;&lt; "Main: threads should be killed" &lt;&lt; endl;
              while (!frame_queue.empty()) {
                  usleep(10000);
              }
              frame_workers.remove_thread(query_thread);
              frame_workers2.remove_thread(query_thread);
              frame_workers.remove_thread(cam0_thread);
              frame_workers2.remove_thread(cam1_thread);
  
              frame_workers.join_all();
              break;
          }
          usleep(10000);
      }
  
      return 0;
  
  }
  </code></pre>
  
  <p>EDIT:</p>
  
  <p>I added a simple function to detect a piece of paper to see if everything is working fine when I don't call on <code>cvShowImage()</code>. My program can detect a piece of paper fine if I don't call <code>cvShowImage()</code>. If I do the program has strange behavior again and freezes etc. </p>