大家下午好!
我一直在使用Visual Studio 2010和OpenCV开发面部识别代码。我试图通过两个线程来完成任务(我需要这样做,因为我将把它应用于一个更大的项目),一个(主要)显示帧,第二个捕获(来自我的笔记本电脑的网络摄像头)并将帧存储在Mat对象上(快速捕获)。
这里不方便的是第二个线程正在捕获帧,但主要没有显示它们。我认为将Mat从捕获线程复制到主线程上的Mat有一个问题(在我进行分配后,“current_frame”似乎是空的)
这是代码(我使用Boost :: Thread for Multithreading)
带有建议的新代码
全球声明
#include <iostream>
#include <stdio.h>
#include <boost\thread.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
boost::mutex mtx;
功能
void camCapture(VideoCapture& cap, Mat& frame, bool* Capture)
{
while (*Capture==true)
{
mtx.lock();
cap >> frame;
mtx.unlock();
if(frame.empty())
{
cout<<"No hay captura"<<endl;
}
else
{
cout<<"Frame capturado"<<endl;
}
}cout << "camCapture finished\n";
return;}
主要
int main() {
try{
VideoCapture cap(0); // open the default camera
Mat frame,current_frame, SFI, Input;
bool *Capture = new bool;
*Capture = true;
if (!cap.isOpened()) // check if we succeeded
return -1;
//your capture thread has started
boost::thread captureThread(camCapture, cap, frame, Capture);
while(1)
{
if(frame.empty())
{
cout<<"Frame en hilo principal vacio"<<endl;
}
else{
cout<<"Frame en hilo principal capturado"<<endl;
}
mtx.lock();
current_frame = frame.clone();
mtx.unlock();
if(current_frame.empty())
{
cout<<"Current_Frame vacio"<<endl;
}
else{
imshow("Streaming",current_frame);
if(waitKey(10)==27)break;
}
}
//Terminate the thread
captureThread.join();
}
catch(Exception & e)
{
cout<<e.what()<<endl;
}
return 0;}
答案 0 :(得分:0)
根据Boost threads - passing parameters by reference,如果要通过引用传递一个变量来调用boost :: thread函数,则必须使用boost::ref(v)
。但你可以改用指针。
此外,您应该通过将它作为指针或引用变量传递给线程来共享互斥锁,而不是将其用作全局:
#include <iostream>
#include <stdio.h>
#include <boost/thread.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
boost::mutex mtx;
void camCapture(VideoCapture& cap, Mat& frame, bool* Capture)
{
while (*Capture == true)
{
mtx.lock();
cap >> frame;
mtx.unlock();
if (frame.empty())
{
cout << "No hay captura" << endl;
}
else
{
cout << "Frame capturado" << endl;
}
}cout << "camCapture finished\n";
return;
}
int main() {
try{
VideoCapture cap(0); // open the default camera
Mat frame, current_frame, SFI, Input;
bool *Capture = new bool; // better not use a pointer here, but use a bool and pass the address or by reference.
*Capture = true;
if (!cap.isOpened()) // check if we succeeded
return -1;
//your capture thread has started
boost::thread captureThread(camCapture, boost::ref(cap), boost::ref(frame), Capture);
while (1)
{
mtx.lock();
current_frame = frame.clone();
mtx.unlock();
if (current_frame.empty())
{
cout << "Current_Frame vacio" << endl;
}
else{
imshow("Streaming", current_frame);
if (waitKey(10) == 27)
{
// TODO: you should use a mutex (or an atomic type) here, too, maybe setting a bool is thread-safe, but this can't be guaranteed for each hardware!
*Capture = false;
break;
}
}
}
//Terminate the thread
captureThread.join();
// give memory free:
delete Capture;
}
catch (Exception & e)
{
cout << e.what() << endl;
}
return 0;
}