使用OpenCV,Boost线程和多个摄像头(Using OpenCV, Boost threading and multiple cameras)

编程入门 行业动态 更新时间:2024-10-24 04:41:03
使用OpenCV,Boost线程和多个摄像头(Using OpenCV, Boost threading and multiple cameras)

我正在尝试编写一个能够从两个不同线程捕获来自两个不同摄像头的图像的程序。 我想这样做,因为当我在同一个线程中执行此操作时,我必须等待cvQueryFrame两倍的时间,因此我无法以30 fps抓取图像(每个相机可以获得15 FPS)。

我看过这篇帖子,但这只适用于一台相机。 一起使用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()我的程序可以检测到一张纸。 如果我的程序又有奇怪的行为,并冻结等。

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).

I have taken a look at this SO post, but this only works for one camera. Using cvQueryFrame and boost::thread together

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

My code:

#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; }

EDIT:

I added a simple function to detect a piece of paper to see if everything is working fine when I don't call on cvShowImage(). My program can detect a piece of paper fine if I don't call cvShowImage(). If I do the program has strange behavior again and freezes etc.

最满意答案

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

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

There should only be one thread manipulating the GUI (this is true for just about any GUI framework). You should organize your code so that cvShowImage is only invoked from the main "GUI thread".

It seems that the work that's being done in query_thread could just as easily be done inside the main thread.

更多推荐

本文发布于:2023-07-24 00:27:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1239285.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:多个   线程   摄像头   Boost   OpenCV

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!