Hope your are doing good ! I'm strugguling from yesterday on how to implement a multithreaded video processing program with opencv.
I understand how threads actually work, how to use a simple mutex etc...But when it comes to implementation, i'm completely lost.
My goal is to create an interface with Qt and display two labels, one showing original video feed and the other showing the processed one, each one handeled by a thread.
For now i'm just trying to get on thread to display images, but i really struggle with it.
Here is what i've done so far :
CaptureThread a class inheriting from QThread : It is supposed to handle the start of cam capture etc...
#include <QThread>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "opencv2/videoio.hpp"
#include <QTimer>
class CaptureThread
: public QThread{
Q_OBJECT
public:
explicit CaptureThread
(QObject *parent
);
protected:
void run();
signals:
void frameCaptured(cv::Mat);
public slots:
void captureFrame();
private:
cv::VideoCapture capWebam;
cv::Mat capturedFrame;
};
#endif // CAPTURETHREAD_H
#include <QThread>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "opencv2/videoio.hpp"
#include <QTimer>
class CaptureThread : public QThread
{
Q_OBJECT
public:
explicit CaptureThread(QObject *parent);
protected:
void run();
signals:
void frameCaptured(cv::Mat);
public slots:
void captureFrame();
private:
QTimer* tmrTimer;
cv::VideoCapture capWebam;
cv::Mat capturedFrame;
};
#endif // CAPTURETHREAD_H
To copy to clipboard, switch view to plain text mode
And this is its implementation :
#include "capturethread.h"
#include <QDebug>
{
capWebam.open(0);
}
void CaptureThread::run()
{
QObject::connect(tmrTimer,
SIGNAL(timeout
()),
this,
SLOT(captureFrame
()));
tmrTimer->start(10);
exec();
}
void CaptureThread::captureFrame()
{
if(capWebam.isOpened()){
capWebam.read(capturedFrame);
emit frameCaptured(capturedFrame);
}
}
#include "capturethread.h"
#include <QDebug>
CaptureThread::CaptureThread(QObject* parent):QThread(parent)
{
capWebam.open(0);
}
void CaptureThread::run()
{
tmrTimer = new QTimer(this);
QObject::connect(tmrTimer, SIGNAL(timeout()), this, SLOT(captureFrame()));
tmrTimer->start(10);
exec();
}
void CaptureThread::captureFrame()
{
if(capWebam.isOpened()){
capWebam.read(capturedFrame);
emit frameCaptured(capturedFrame);
}
}
To copy to clipboard, switch view to plain text mode
MainWindow use to display the camera feed etc...
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "opencv2/videoio.hpp"
#include <capturethread.h>
#include <QTimer>
namespace Ui {
class MainWindow;
}
{
Q_OBJECT
public:
explicit MainWindow
(QWidget *parent
= 0);
~MainWindow();
public slots:
void pricessFrameAndUpdateGUI(cv::Mat matOriginal);
private slots:
void on_button_clicked();
private:
Ui::MainWindow *ui;
cv::VideoCapture capWebcam;
cv::Mat matOriginal;
cv::Mat matProcessed;
CaptureThread* cpThread;
};
#endif // MAINWINDOW_H
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "opencv2/videoio.hpp"
#include <capturethread.h>
#include <QTimer>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void pricessFrameAndUpdateGUI(cv::Mat matOriginal);
private slots:
void on_button_clicked();
private:
Ui::MainWindow *ui;
QImage toGrayscale(QImage image);
cv::VideoCapture capWebcam;
cv::Mat matOriginal;
cv::Mat matProcessed;
QImage qimgOriginal;
QImage qimgProcessed;
QTimer* tmrTimer;
CaptureThread* cpThread;
};
#endif // MAINWINDOW_H
To copy to clipboard, switch view to plain text mode
its implementaion
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtCore>
#include <cv.h>
#include <QColor>
#include <opencv/highgui.h>
{
ui->setupUi(this);
cpThread = new CaptureThread(this);
QObject::connect(cpThread,
SIGNAL(frameCaptured
(cv
::Mat)),
this,
SLOT(pricessFrameAndUpdateGUI
(cv
::Mat)));
cpThread->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::pricessFrameAndUpdateGUI(cv::Mat matOriginal)
{
cv::Canny(matOriginal, matProcessed, 100, 300);
cv::cvtColor(matOriginal, matOriginal, CV_BGR2RGB);
QImage qimgOriginal
((uchar
*)matOriginal.
data, matOriginal.
cols, matOriginal.
rows, matOriginal.
step,
QImage::Format_RGB888);
QImage qimgProcessed
((uchar
*)matProcessed.
data, matProcessed.
cols, matProcessed.
rows, matProcessed.
step,
QImage::Format_Indexed8);
ui
->original
->setPixmap
(QPixmap::fromImage(qimgOriginal
));
ui
->modified
->setPixmap
(QPixmap::fromImage(qimgProcessed
));
}
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtCore>
#include <cv.h>
#include <QColor>
#include <opencv/highgui.h>
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
ui->setupUi(this);
cpThread = new CaptureThread(this);
QObject::connect(cpThread, SIGNAL(frameCaptured(cv::Mat)),this, SLOT(pricessFrameAndUpdateGUI(cv::Mat)));
cpThread->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::pricessFrameAndUpdateGUI(cv::Mat matOriginal)
{
cv::Canny(matOriginal, matProcessed, 100, 300);
cv::cvtColor(matOriginal, matOriginal, CV_BGR2RGB);
QImage qimgOriginal((uchar*)matOriginal.data, matOriginal.cols, matOriginal.rows, matOriginal.step, QImage::Format_RGB888);
QImage qimgProcessed((uchar*)matProcessed.data, matProcessed.cols, matProcessed.rows, matProcessed.step,QImage::Format_Indexed8);
ui->original->setPixmap(QPixmap::fromImage(qimgOriginal));
ui->modified->setPixmap(QPixmap::fromImage(qimgProcessed));
}
To copy to clipboard, switch view to plain text mode
After compiling and executing the program i get this error :
Starting /media/wassim/BLAZER/Workspace/CPP/build-firstCV-Desktop_Qt_5_3_GCC_64bit-Debug/firstCV...
VIDEOIO ERROR: V4L/V4L2: VIDIOC_S_CROP
QObject: Cannot create children
for a parent that is in a different thread.
(Parent is CaptureThread(0xc02be0), parent's thread is QThread(0xae82c0), current thread is CaptureThread(0xc02be0)
The program has unexpectedly finished.
/media/wassim/BLAZER/Workspace/CPP/build-firstCV-Desktop_Qt_5_3_GCC_64bit-Debug/firstCV crashed
Starting /media/wassim/BLAZER/Workspace/CPP/build-firstCV-Desktop_Qt_5_3_GCC_64bit-Debug/firstCV...
VIDEOIO ERROR: V4L/V4L2: VIDIOC_S_CROP
QObject: Cannot create children for a parent that is in a different thread.
(Parent is CaptureThread(0xc02be0), parent's thread is QThread(0xae82c0), current thread is CaptureThread(0xc02be0)
The program has unexpectedly finished.
/media/wassim/BLAZER/Workspace/CPP/build-firstCV-Desktop_Qt_5_3_GCC_64bit-Debug/firstCV crashed
To copy to clipboard, switch view to plain text mode
Thanks you guys for your help !
Bookmarks