【QT】多线程+OpenCV的demo
结合最近学的知识自己做了个小demo。可以实现对输入的图片进行图像处理,高斯模糊、灰度处理以及边缘检测,三种处理同时进行。
思路:借助OpenCv库,用Mat读取图片并输出展示在界面上,多线程进行图像处理。这里采用线程池的方法。
ui界面如下
Mythread.h
#pragma once
#include "qobject.h"
#include
#include
#include
#include
#include
#include
using namespace std;
using namespace cv;
class Gaussuianintroduce :public QObject, public QRunnable
{
Q_OBJECT
public:
Gaussuianintroduce();
~Gaussuianintroduce();
void run();
void recvmat(Mat mat);
signals:
void finish(Mat mat);
private:
Mat m_mat;
Mat mat_Gussian;
};
class Grayintroduce :public QObject, public QRunnable
{
Q_OBJECT
public:
Grayintroduce();
~Grayintroduce();
void run();
void recvmat(Mat mat);
signals:
void finish(Mat mat);
private:
Mat m_mat2;
Mat mat_Gray;
};
class Cannyintroduce :public QObject, public QRunnable
{
Q_OBJECT
public:
Cannyintroduce();
~Cannyintroduce();
void run();
void recvmat(Mat mat);
signals:
void finish(Mat mat);
private:
Mat m_mat3;
Mat mat_Canny;
};
Mythread.cpp
#include "Mythread.h"
#include
#include
#include
#include
#include
#include
#include
#include
#pragma execution_character_set("utf-8")
#include
#include
#include
#include
#include
using namespace cv;
using namespace std;
Gaussuianintroduce::Gaussuianintroduce()
{
setAutoDelete(true);
}
Gaussuianintroduce::~Gaussuianintroduce()
{
}
void Gaussuianintroduce::run()
{
qDebug() << "高斯模糊处理的线程地址:" << QThread::currentThread();
QElapsedTimer time;
time.start();
GaussianBlur(m_mat, mat_Gussian, Size(29, 29), 0, 0);
int milsec = time.elapsed();
qDebug() << "高斯模糊处理用时" << milsec << "毫秒";
emit finish(mat_Gussian);
}
void Gaussuianintroduce::recvmat(Mat mat)
{
m_mat = mat;
}
Grayintroduce::Grayintroduce()
{
setAutoDelete(true);
}
Grayintroduce::~Grayintroduce()
{
}
void Grayintroduce::run()
{
qDebug() << "灰度处理的线程地址:" << QThread::currentThread();
QElapsedTimer time;
time.start();
cvtColor(m_mat2, mat_Gray, COLOR_BGR2GRAY);
int milsec = time.elapsed();
qDebug() << "灰度处理用时" << milsec << "毫秒";
emit finish(mat_Gray);
}
void Grayintroduce::recvmat(Mat mat)
{
m_mat2 = mat;
}
Cannyintroduce::Cannyintroduce()
{
setAutoDelete(true);
}
Cannyintroduce::~Cannyintroduce()
{
}
void Cannyintroduce::run()
{
qDebug() << "边缘检测的线程地址:" << QThread::currentThread();
QElapsedTimer time;
time.start();
Canny(m_mat3, mat_Canny, 150, 100, 3);
int milsec = time.elapsed();
qDebug() << "灰度处理用时" << milsec << "毫秒";
emit finish(mat_Canny);
}
void Cannyintroduce::recvmat(Mat mat)
{
m_mat3 = mat;
}
demo_qt_cv_thread.h
#pragma once
#include
#include "ui_demo_qt_cv_thread.h"
#include
#include
using namespace std;
using namespace cv;
class demo_qt_cv_thread : public QMainWindow
{
Q_OBJECT
public:
demo_qt_cv_thread(QWidget *parent = Q_NULLPTR);
QImage MatToImage(Mat &mat);
signals:
void starting(Mat mat);
private:
Ui::demo_qt_cv_threadClass *ui;
Mat image;
};
demo_qt_cv_thread.cpp
#include "demo_qt_cv_thread.h"
#include
#include
#include
#include
#pragma execution_character_set("utf-8")
#include
#include
#include "Mythread.h"
#include
#include
#include
using namespace std;
using namespace cv;
demo_qt_cv_thread::demo_qt_cv_thread(QWidget *parent)
: QMainWindow(parent)
{
ui->setupUi(this);
this->setWindowTitle("多线程图像处理");
this->setWindowIcon(QPixmap(":/res/b2.jpg"));
connect(ui->pushButton_2, &QPushButton::clicked, [=]() {
ui->label->clear();
ui->label_2->clear();
ui->label_3->clear();
ui->label_4->clear();
QString filename = QFileDialog::getOpenFileName(this,
tr("open image"), ".", tr("Image file(*.png *.jpg *.bmp)")
);
image = imread(filename.toLocal8Bit().data());
qDebug() << image.data;
if (image.empty())
{
QMessageBox::information(this, tr("提示"), tr("未成功载入图片"), QMessageBox::Ok);
}
QPixmap pix;
pix = QPixmap::fromImage(MatToImage(image).scaled(ui->label->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
ui->label->setPixmap(pix);
});
Gaussuianintroduce *th1 = new Gaussuianintroduce;
Grayintroduce *th2 = new Grayintroduce;
Cannyintroduce *th3 = new Cannyintroduce;
connect(this, &demo_qt_cv_thread::starting, th1, &Gaussuianintroduce::recvmat);
connect(this, &demo_qt_cv_thread::starting, th2, &Grayintroduce::recvmat);
connect(this, &demo_qt_cv_thread::starting, th3, &Cannyintroduce::recvmat);
connect(ui->pushButton, &QPushButton::clicked, [=]() {
ui->label_2->clear();
ui->label_3->clear();
ui->label_4->clear();
QThreadPool::globalInstance()->start(th1);
QThreadPool::globalInstance()->start(th2);
QThreadPool::globalInstance()->start(th3);
emit starting(image);
});
connect(th1, &Gaussuianintroduce::finish, [=](Mat mat_Gussian) {
QPixmap pix2;
pix2 = QPixmap::fromImage(MatToImage(mat_Gussian).scaled(ui->label_2->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
ui->label_2->setPixmap(pix2);
});
connect(th2, &Grayintroduce::finish, [=](Mat mat_Gray) {
QPixmap pix3;
pix3 = QPixmap::fromImage(MatToImage(mat_Gray).scaled(ui->label_3->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
ui->label_3->setPixmap(pix3);
});
connect(th3, &Cannyintroduce::finish, [=](Mat mat_Canny) {
QPixmap pix4;
pix4 = QPixmap::fromImage(MatToImage(mat_Canny).scaled(ui->label_4->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
ui->label_4->setPixmap(pix4);
});
destroyAllWindows();
}
QImage demo_qt_cv_thread::MatToImage(Mat &mat)
{
if (mat.type() == CV_8UC3)
{
const uchar* pSrc = (const uchar*)mat.data;
QImage image(pSrc, mat.cols, mat.rows,(mat.cols)*3, QImage::Format_RGB888);
return image.rgbSwapped();
}
else if (mat.type() == CV_8UC1)
{
QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
image.setColorCount(256);
for (int i = 0; i < 256; i++)
{
image.setColor(i, qRgb(i, i, i));
}
uchar *pSrc = mat.data;
for (int row = 0; row < mat.rows; row++)
{
uchar *pDest = image.scanLine(row);
memcpy(pDest, pSrc, mat.cols);
pSrc += mat.step;
}
return image;
}
else if (mat.type() == CV_8UC4)
{
qDebug() << "CV_8UC4";
const uchar *pSrc = (const uchar*)mat.data;
QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
return image.copy();
}
else
{
qDebug() << "ERROR:Mat could not be converted to QImage";
return QImage();
}
}
运行效果如下:
点击输入图片按钮,弹出一个文件夹,可选取自己想处理的图片
这里我选择了一张狗头的表清包
点击开始处理按钮,成功实现同时输出三种处理图像
通过调试信息可以看到
Original: https://blog.csdn.net/Sca_Lian/article/details/126115868
Author: 我也不太懂她
Title: Qt+多线程实现单幅图像高斯、灰度、边缘处理,调用opencv库导入图片
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/642214/
转载文章受原作者版权保护。转载请注明原作者出处!