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

时间:2016-04-02 22:44:40

标签: c++ multithreading visual-studio-2010 opencv

大家下午好!

我一直在使用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;}

1 个答案:

答案 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;
}