Opencv video writing
-
I have opencv code in C++ side and Buttons like start,stop,pause are in qml side properly connected with this c++ side. When I press the start button,it starts to write. but when i hit the stop button,it crashes sometimes but not all the times. this is the code snippet where all the variable and function declaration have been made in the d=header file:
#include "videostreamer.h" #include "opencv2/imgproc.hpp" #include <opencv2/opencv.hpp> #include <QDateTime> #include <opencv2/core.hpp> // Basic OpenCV structures (cv::Mat) #include <opencv2/videoio.hpp> // Video write #include <opencv2/core.hpp> // Basic OpenCV structures (cv::Mat) #include <opencv2/videoio.hpp> // Video write #include "opencv2/highgui/highgui.hpp" #include <chrono> #include <ctime> #include <cmath> using namespace cv; static cv::VideoWriter video; static bool recording_status=false; VideoStreamer::VideoStreamer() { cap.set(cv::CAP_PROP_FPS,25); connect(&tUpdate,&QTimer::timeout,this,&VideoStreamer::streamVideo); } VideoStreamer::~VideoStreamer() { tUpdate.stop(); threadStreamer->requestInterruption(); } void VideoStreamer::streamVideo() { QImage img = QImage(frame.data,frame.cols,frame.rows,QImage::Format_RGB888).rgbSwapped(); emit newImage(img); } void VideoStreamer::catchFrame(cv::Mat emittedFrame) { frame = emittedFrame; } void VideoStreamer::releaseCurrentStream() { threadStreamer->requestInterruption(); cap.release(); tUpdate.stop(); } void VideoStreamer::openVideoCamera(QString path) { if(path.length() == 1) cap.open(path.toInt()); else cap.open(path.toStdString()); VideoStreamer* worker = new VideoStreamer(); worker->moveToThread(threadStreamer); QObject::connect(threadStreamer,SIGNAL(started()),worker,SLOT(streamerThreadSlot())); QObject::connect(worker,&VideoStreamer::emitThreadImage,this,&VideoStreamer::catchFrame); threadStreamer->start(); double fps = cap.get(cv::CAP_PROP_FPS); qDebug()<<"fps"<<cap.get(cv::CAP_PROP_FPS); tUpdate.start(1); } void VideoStreamer::streamerThreadSlot() { cv::Mat tempFrame; while (1) { cap>>tempFrame; if(tempFrame.data) { emit emitThreadImage(tempFrame); } if(recording_status) { video.write(tempFrame); } else { } if(QThread::currentThread()->isInterruptionRequested()) { cap.release(); video.release(); return; } } } void VideoStreamer::start_recording() { int frame_width = cap.get(cv::CAP_PROP_FRAME_WIDTH); int frame_height = cap.get(cv::CAP_PROP_FRAME_HEIGHT); recording_status=true; video.open("output.avi",cv::VideoWriter::fourcc('M','J','P','G'), 30,Size(frame_width,frame_height),true); } void VideoStreamer::stop_recording() { if (video.isOpened()) { video.release(); recording_status=false; } }
-
@Vijaykarthikeyan said in Opencv video writing:
@SGaist So I have to release the video variable after changing the state recording status to false..isn't it?
You have to release them after the thread has stopped writing to the file. So it should rather be:
- Request recording to stop
- Emit recording has stopped when done
- Cleanup in response to that signal
-
@Vijaykarthikeyan
If it "crashes" have you run under a debugger? Post the stack trace for a clue. -
@Vijaykarthikeyan beside the good point of @JonB, you have a multi-threaded system and you are basically closing everything before changing the variable that pilots whether the recoding happens.
You should refactor that code to properly handle the state changes and especially take into account the fact that you are using multiple threads and thus should either write proper lock free code or use proper locking when accessing variables from multiple threads.
-
@Vijaykarthikeyan
Nothing to do with Qt per se. You have a C++ program. Run it under a debugger. If it "crashes" it will tell you so and stop. Debugger/IDE will have some window/pane for "stack trace". Very useful to learn to run C++ programs under a debugger and get that to show stack traces, variable values etc. -
@Vijaykarthikeyan said in Opencv video writing:
@SGaist So I have to release the video variable after changing the state recording status to false..isn't it?
You have to release them after the thread has stopped writing to the file. So it should rather be:
- Request recording to stop
- Emit recording has stopped when done
- Cleanup in response to that signal
-