Visual Studio 2010 OpenCV 多线程垫不复制到另一个垫

Visual Studio 2010 OpenCV Multithread Mat does not copy to another Mat

大家下午好!

我一直在使用 Visual Studio 2010 和 OpenCV 开发人脸识别代码。我试图通过两个线程来完成任务(我需要这样做,因为我要把它应用到一个更大的项目上),一个(主要)显示帧,第二个捕获(来自我笔记本电脑的网络摄像头)并将帧存储在 Mat 对象上(快速捕获)。

这里不方便的是第二个线程正在捕获帧,但主线程没有显示它们。我认为将捕获线程中的 Mat 复制到主线程上的 Mat 存在问题("current_frame" 在我进行分配后似乎是空的)

这是代码(我使用 Boost::Thread 进行多线程处理)

带有建议的新代码

全局声明

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

根据 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;
}