使用OpenCV,Boost线程和多个摄像头

我试图编写一个程序,能够从两个不同的线程捕捉来自两个不同的摄像头的图像。 我想这样做,因为当我在同一个线程中,我必须不断等待cvQueryFrame两倍的时间,所以我不能以30 fps抓取图像(我从每个相机得到15 FPS)。

我看了这个post,但这只适用于一个摄像头。 一起使用cvQueryFrame和boost :: thread

我目前的程序给出了不同的结果,有时它会导致内存泄漏,通常我只是没有看到任何事情发生,有时它几秒钟,但图像冻结了。 奇怪的是,更早的时候,我没有调用cvShowImage,但有我的imageProcessing函数做一些有用的事情,我可以看到,我从两个相机获得实时结果。 我认为这意味着有可能做这个工作,但是我在某个地方犯了一个愚蠢的错误。 我的操作系统是LINUX,我正在使用OpenCV 2.4

我的代码:

#include <iostream> #include <cstdio> #include <cv.h> #include <ml.h> #include <cvaux.h> #include <highgui.h> #include <vector> #include <stdio.h> #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<IplImage* > * frame_queue, int camNumber) { try { //Load first frames cout << "grabFrame: " << camNumber << " init with " << cameraWidth << " x " << cameraHeight << endl; IplImage* frame; if (camNumber == 0)frame = cvQueryFrame(capture); if (camNumber == 1)frame = cvQueryFrame(capture2); while (frame && !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 << "grabFrame: " << camNumber << " pushing back to queue" << endl; frame_queue->push(frame_copy); int k = cvWaitKey(waitKeyValue); if (k == 1048603 || k == 27 || k == '\r') { cout << "grabFrame: Process killed" << endl; //release memory threads_should_exit = true; } } } catch (const concurrent_queue<IplImage* >::Canceled & e) { cout << "grabFrame: Show thread is canceled" << endl; return; } } void processFrames(concurrent_queue<IplImage* > * frame_queue0, concurrent_queue<IplImage* > * frame_queue1) { try { do { cout << "processFrames: Processing two frames" << endl; IplImage* frm = NULL; frame_queue0->wait_and_pop(frm); IplImage * frm2 = NULL; frame_queue1->wait_and_pop(frm2); cvReleaseImage(&frm); cvReleaseImage(&frm2); } while (!threads_should_exit); } catch (const concurrent_queue<IplImage* >::Canceled & e) { cout << "processFrames: Processing thread is canceled" << 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<IplImage* > frame_queue(&frame_workers); concurrent_queue<IplImage* > frame_queue2(&frame_workers2); boost::thread * query_thread = new boost::thread(processFrames, &frame_queue, &frame_queue2); boost::thread * cam0_thread = new boost::thread(grabFrame, &frame_queue, 0); usleep(10000); boost::thread * cam1_thread = new boost::thread(grabFrame, &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 << "Main: threads should be killed" << 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; } 

编辑:

我添加了一个简单的函数来检测一张纸,看看是否一切正常工作,当我不呼吁cvShowImage() 。 我的程序可以检测一张纸罚款,如果我不叫cvShowImage() 。 如果我的程序又有奇怪的行为,并冻结等

应该只有一个线程操作GUI(对于任何GUI框架都是如此)。 您应该组织您的代码,以便cvShowImage只从主“GUI线程”调用。

看来在query_thread中完成的工作可以在主线程中轻松完成。