简体   繁体   中英

Boost/OpenCV error: no match for call to '(boost::_mfi::dm<void(cv::Mat*, cv::VideoCapture*), Recorder>)

I'm want to achieve a "smooth" video recording using OpenCV and the Boost libaries. For that i'm trying to implement the code I found here in to my program. I'm not too familiar with Boost yet and I keep getting the error \\bind.hpp:313: error: no match for call to '(boost::_mfi::dm) (cv::Mat*&, cv::VideoCapture*&)' unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]);

My code is the following:

#include "recorder.h"
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "boost/thread.hpp"


using namespace cv;
using namespace std;
using namespace boost::posix_time;

Recorder::Recorder(){ 

     webcamRecorder.open(1);
     webcamRecorder.set(CV_CAP_PROP_FRAME_WIDTH, 1920);
     webcamRecorder.set(CV_CAP_PROP_FRAME_HEIGHT, 1080);
     recordingCount=0;
     filename = "F:/MyVideo";
     ext=".avi";
     hasStarted=false;  
}

void Recorder::captureFunc(Mat *matRecorder, VideoCapture *webcamRecorder){
      for(;;){
            //capture from webcame to Mat frame
            (*webcamRecorder) >> (*matRecorder);
            resize(*matRecorder,matOut,Size(1280,720),0,0,INTER_LINEAR);
        }
}
void Recorder::setup(){
    if (!hasStarted){
        this->start();
        boost::thread captureThread(&Recorder::captureFunc, &matRecorder, &webcamRecorder);

    }
}
void Recorder::run(){
    cout << "++++++++recorder thread called+++" << endl;

    theVideoWriter.open(filename+countAsString+ext,CV_FOURCC('L','A','G','S'), 30, Size(1280,720), true);

    nextFrameTimestamp = microsec_clock::local_time();
    currentFrameTimestamp = nextFrameTimestamp;
    td = (currentFrameTimestamp - nextFrameTimestamp);    

    if ( theVideoWriter.isOpened() == false ){
        cout << "ERROR: Failed to write the video" << endl;
    }
    if (recording){
        while(recording){
            hasStarted=true;
            while(td.total_microseconds() < 1000000/30){
            //determine current elapsed time
                currentFrameTimestamp = microsec_clock::local_time();
                td = (currentFrameTimestamp - nextFrameTimestamp);
            }

            //       determine time at start of write
            initialLoopTimestamp = microsec_clock::local_time();

            theVideoWriter << matOut; // write video file

            nextFrameTimestamp = nextFrameTimestamp + microsec(1000000/30);
            td = (currentFrameTimestamp - nextFrameTimestamp);

            finalLoopTimestamp = microsec_clock::local_time();
            td1 = (finalLoopTimestamp - initialLoopTimestamp);
            delayFound = td1.total_milliseconds();
            cout << delayFound << endl;

        }
    }
    hasStarted=false;
    cout << "finished recording" << endl;
    theVideoWriter.release();
    recordingCount++;
    countAsString = static_cast<ostringstream*>( &(ostringstream() << recordingCount) )->str();

}
void Recorder::setRecording(bool x){ recording = x;}

What is wrong with my implementation? Again the original code pieces are from here

The problem, and the difference between your case and the link you provided, is that you use an object method for the thread function. Specifically:

boost::thread captureThread(&Recorder::captureFunc, &matRecorder, &webcamRecorder);

An object method needs a pointer for this . Since you create the thread in an object method, you can use its this pointer:

boost::thread captureThread(&Recorder::captureFunc, this, &matRecorder, &webcamRecorder);

Some general suggestions:

  1. You don't need boost for threads anymore. C++11 has it in its standard library. I suggest you use it if you can.
  2. The thread you created becomes detached - it continues executing, but you can't control it. You probably want to save it somewhere, so you can join it later.

To have the thread as an instance variable:

  1. Have the thread declared in the class definition: std::thread captureThread; .
  2. Have it initialized in the current function, and moved to the instance variable:

    std::thread localCaptureThread(&Recorder::captureFunc, this, &matRecorder, &webcamRecorder); captureThread = std::move(localCaptureThread);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM