Note that there are some explanatory texts on larger screens.

plurals
  1. POUsing OpenCV, Boost threading and multiple cameras
    text
    copied!<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>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload