我这里有一个代码,用于从在单独线程中运行视频捕获操作的摄像机捕获视频流。代码可以编译,但是当我尝试运行它时,我收到以下错误。
我做了一些研究,发现此问题与缺少th.join();
有关,但是当用户通过按下q
键中断该过程时,我已经这样做了。在此之前,代码应继续在创建的线程中运行。所以这告诉我应该在其他地方加入线程。
如果我通过将thread th(&VideoCaptureAsync::update,this);
替换为VideoCaptureAsync::update();
并删除th.join();
来删除线程,则错误消失了,但这显然违反了此代码的目的。
输出
内部启动功能
(进程:10748):GStreamer-CRITICAL **:gst_element_get_state: 断言“ GST_IS_ELEMENT(元素)”失败
内部启动功能
内部更新功能
在没有活动异常的情况下终止调用
内部读取功能
已中止(核心已弃用)
代码
/*
* Asynchronous_video_capture.cpp
*
* Copyright (C) 2019 C. S. G.
*
* MIT License
*/
#include <iostream> // for standard I/O
#include <string> // for strings
#include <opencv2/highgui.hpp>
#include <opencv2/core.hpp> // Basic OpenCV structures (cv::Mat)
#include <opencv2/videoio.hpp> // Video write
#include <opencv2/opencv.hpp>
#include <opencv2/core/utility.hpp>
#include <thread>
#include <tuple>
using namespace cv;
using namespace std;
void foo(bool &keep_run){
cout << "Inside the thread: Interrupt flag = " << keep_run << endl;
if (std::cin.get() == 'q') {
keep_run = false;
cout << "User Interrupted the process. Interrupt flag = " << keep_run << endl;
}
}
class VideoCaptureAsync
{
private:
VideoCapture cam;
thread th;
bool read_lock;
Mat frame;
Mat grabbed;
bool isStarted;
public:
void initiate(unsigned int camId,unsigned int width,unsigned int height,double fps);
void start(); // a start function to create and start the thread
void update(); // an update function that will be called asynchronously
tuple<Mat,Mat> read(); // a read function that we will call from our code to retrieve a new frame.
void stop(); // a stop function to stop (join) the thread
void exit(); // an __exit__ function to clean up some resources.
};
void VideoCaptureAsync::initiate(unsigned int camId,double fps){
cout << "Inside initiate function" << endl;
cam.open(camId);
if (!cam.isOpened())
{
cerr << "Could not open the VideoCapture camera: " << camId << endl;
}
cam.set(CV_CAP_PROP_FRAME_WIDTH,width);
cam.set(CV_CAP_PROP_FRAME_HEIGHT,height);
cam.set(CAP_PROP_FPS,fps);
isStarted = false;
read_lock = false;
VideoCaptureAsync::start();
}
void VideoCaptureAsync::start(){
cout << "Inside start function" << endl;
if (isStarted) {
cout << "Asynchroneous video capturing has already been started" << endl;
}
isStarted = true;
thread th(&VideoCaptureAsync::update,this);
//VideoCaptureAsync::update();
}
void VideoCaptureAsync::update(){
cout << "Inside update function" << endl;
while(isStarted){
Mat frame_update;
Mat grabbed_update;
tie(frame_update,grabbed_update) = VideoCaptureAsync::read();
if(!read_lock){
frame_update.copyTo(frame);
grabbed_update.copyTo(grabbed);
}
}
}
tuple<Mat,Mat> VideoCaptureAsync::read(){
cout << "Inside read function" << endl;
if (!read_lock){
read_lock = true;
Mat frame_read;
cam.read(frame_read);
Mat grabbed_read;
read_lock = false;
return make_tuple(frame_read,grabbed_read);
}
}
void VideoCaptureAsync::stop(){
cout << "Inside stop function" << endl;
th.join();
isStarted = false;
read_lock = true;
}
void VideoCaptureAsync::exit(){
cout << "Finished writing ..." << endl;
cam.release();
}
int main(int argc,char *argv[]){
const unsigned int camId = 1;
const bool enableOutput = true;
const unsigned int w = 1280;
const unsigned int h = 720;
double fps = 30.0;
VideoCaptureAsync obj;
obj.initiate(camId,w,h,fps);
bool keep_running = true;
thread th1(foo,std::ref(keep_running));
Mat original_frame;
while (keep_running) {
std::tie(std::ignore,original_frame) = obj.read();
if (enableOutput) {
imshow("Retrieved Image",original_frame);
waitKey(1000/fps);
}
}
obj.stop();
obj.exit();
}