
QImage与OpenCV的cv::Mat数据转换
opencv
OpenCV: 开源计算机视觉库
项目地址:https://gitcode.com/gh_mirrors/opencv31/opencv

·
在Qt中使用OpenCV,经常是用QImage与OpenCV的mat进行数据转换,最终显示都是转成QImage或QPixmap的数据,本篇介绍QImage与cv::Mat的数据转换。
1.QImage读取图片转换成cv::Mat
首先通过QImage加载图片image.load(":/image/t2.jpg");
然后通过QImageToMat函数转成cv::Mat
cv::Mat QImageToMatDialog::QImageToMat(const QImage &image)
{
cv::Mat mat;
switch(image.format())
{
case QImage::Format_Grayscale8: // 灰度图,每个像素点1个字节(8位)
// Mat构造:行数,列数,存储结构,数据,step每行多少字节
mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());
break;
case QImage::Format_ARGB32: // uint32存储0xAARRGGBB,pc一般小端存储低位在前,所以字节顺序就成了BGRA
case QImage::Format_RGB32: // Alpha为FF
// case QImage::Format_ARGB32_Premultiplied:
// mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());
// break;
case QImage::Format_ARGB32_Premultiplied:
{
mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());
std::vector<cv::Mat>channels;
split(mat, channels);
channels.pop_back();
cv::merge(channels, mat);
return mat;
}
case QImage::Format_RGB888: // RR,GG,BB字节顺序存储
mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());
return mat.clone();
break;
case QImage::Format_RGBA64: // uint64存储,顺序和Format_ARGB32相反,RGBA
mat = cv::Mat(image.height(), image.width(), CV_16UC4, (void*)image.constBits(), image.bytesPerLine());
// opencv需要转为BGRA的字节顺序
cv::cvtColor(mat, mat, cv::COLOR_RGBA2BGRA);
break;
case QImage::Format_Mono:
case QImage::Format_MonoLSB:
{
QImage rgbImage = image.convertToFormat(QImage::Format_Grayscale8);
return cv::Mat(rgbImage.height(), rgbImage.width(), CV_8UC1, (void*)rgbImage.bits(), rgbImage.bytesPerLine()).clone();
}
case QImage::Format_Indexed8:
{
mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());
return mat.clone();
}
default:
return mat;
}
return mat;
}
通过cv::imwrite函数保存图片,即
cv::Mat mat = QImageToMat(image);
cv::imwrite("./mat_t2.jpg", mat);
void QImageToMatDialog::slotQImageToMat()
{
QImage image;
bool isLoad = image.load(":/image/t2.jpg");
if(isLoad)
{
QPixmap pixOrg = QPixmap::fromImage(image);
pixOrg = pixOrg.scaled(400, 300);
ui->label->setPixmap(pixOrg);
cv::Mat mat = QImageToMat(image);
cv::imwrite("./mat_t2.jpg", mat);//保存到本地
ui->label_1->setPixmap(pixOrg);
}
}
2..opencv读取图片转成QImage
cv::Mat mat = cv::imread("./t3.jpg");
通过QImage matToQImage(const cv::Mat &mat)函数转成QImage数据
QImage QImageToMatDialog::matToQImage(const cv::Mat &mat)
{
QImage image;
switch(mat.type())
{
case CV_8UC1:
// QImage构造:数据,宽度,高度,每行多少字节,存储结构
image = QImage((const unsigned char*)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_Grayscale8);
break;
case CV_8UC3:
image = QImage((const unsigned char*)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
image = image.rgbSwapped(); // BRG转为RGB
// Qt5.14增加了Format_BGR888
// image = QImage((const unsigned char*)mat.data, mat.cols, mat.rows, mat.cols * 3, QImage::Format_BGR888);
break;
case CV_8UC4:
image = QImage((const unsigned char*)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
break;
case CV_16UC4:
image = QImage((const unsigned char*)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGBA64);
image = image.rgbSwapped(); // BRG转为RGB
break;
default:
break;
}
return image;
}
使用:
opencv
OpenCV: 开源计算机视觉库
项目地址:https://gitcode.com/gh_mirrors/opencv31/opencv
void QImageToMatDialog::slotMatToQImage()
{
cv::Mat mat = cv::imread("./t3.jpg");
QImage image = matToQImage(mat);
QPixmap pix2 = QPixmap::fromImage(image);
pix2 = pix2.scaled(400, 300);
ui->label_2->setPixmap(pix2);
}
完整代码
#ifndef QIMAGETOMATDIALOG_H
#define QIMAGETOMATDIALOG_H
#include <QDialog>
#include "opencv2/opencv.hpp"
using namespace cv;
QT_BEGIN_NAMESPACE
namespace Ui { class QImageToMatDialog; }
QT_END_NAMESPACE
class QImageToMatDialog : public QDialog
{
Q_OBJECT
public:
QImageToMatDialog(QWidget *parent = nullptr);
~QImageToMatDialog();
void initView();
cv::Mat QImageToMat(const QImage &image);
QImage matToQImage(const cv::Mat& mat);
public slots:
void slotQImageToMat();
void slotMatToQImage();
private:
Ui::QImageToMatDialog *ui;
};
#endif // QIMAGETOMATDIALOG_H
#include "qimagetomatdialog.h"
#include "ui_qimagetomatdialog.h"
#include <QDebug>
#include <QImage>
#include <QPixmap>
QImageToMatDialog::QImageToMatDialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::QImageToMatDialog)
{
ui->setupUi(this);
initView();
}
QImageToMatDialog::~QImageToMatDialog()
{
delete ui;
}
void QImageToMatDialog::initView()
{
connect(ui->btnQImageToMat, SIGNAL(clicked()), this, SLOT(slotQImageToMat()));
connect(ui->btnMatToQImage, SIGNAL(clicked()), this, SLOT(slotMatToQImage()));
}
cv::Mat QImageToMatDialog::QImageToMat(const QImage &image)
{
cv::Mat mat;
switch(image.format())
{
case QImage::Format_Grayscale8: // 灰度图,每个像素点1个字节(8位)
// Mat构造:行数,列数,存储结构,数据,step每行多少字节
mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());
break;
case QImage::Format_ARGB32: // uint32存储0xAARRGGBB,pc一般小端存储低位在前,所以字节顺序就成了BGRA
case QImage::Format_RGB32: // Alpha为FF
// case QImage::Format_ARGB32_Premultiplied:
// mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());
// break;
case QImage::Format_ARGB32_Premultiplied:
{
mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());
std::vector<cv::Mat>channels;
split(mat, channels);
channels.pop_back();
cv::merge(channels, mat);
return mat;
}
case QImage::Format_RGB888: // RR,GG,BB字节顺序存储
mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());
return mat.clone();
break;
case QImage::Format_RGBA64: // uint64存储,顺序和Format_ARGB32相反,RGBA
mat = cv::Mat(image.height(), image.width(), CV_16UC4, (void*)image.constBits(), image.bytesPerLine());
// opencv需要转为BGRA的字节顺序
cv::cvtColor(mat, mat, cv::COLOR_RGBA2BGRA);
break;
case QImage::Format_Mono:
case QImage::Format_MonoLSB:
{
QImage rgbImage = image.convertToFormat(QImage::Format_Grayscale8);
return cv::Mat(rgbImage.height(), rgbImage.width(), CV_8UC1, (void*)rgbImage.bits(), rgbImage.bytesPerLine()).clone();
}
case QImage::Format_Indexed8:
{
mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());
return mat.clone();
}
default:
return mat;
}
return mat;
}
QImage QImageToMatDialog::matToQImage(const cv::Mat &mat)
{
QImage image;
switch(mat.type())
{
case CV_8UC1:
// QImage构造:数据,宽度,高度,每行多少字节,存储结构
image = QImage((const unsigned char*)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_Grayscale8);
break;
case CV_8UC3:
image = QImage((const unsigned char*)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
image = image.rgbSwapped(); // BRG转为RGB
// Qt5.14增加了Format_BGR888
// image = QImage((const unsigned char*)mat.data, mat.cols, mat.rows, mat.cols * 3, QImage::Format_BGR888);
break;
case CV_8UC4:
image = QImage((const unsigned char*)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
break;
case CV_16UC4:
image = QImage((const unsigned char*)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGBA64);
image = image.rgbSwapped(); // BRG转为RGB
break;
default:
break;
}
return image;
}
void QImageToMatDialog::slotQImageToMat()
{
QImage image;
bool isLoad = image.load(":/image/t2.jpg");
if(isLoad)
{
QPixmap pixOrg = QPixmap::fromImage(image);
pixOrg = pixOrg.scaled(400, 300);
ui->label->setPixmap(pixOrg);
cv::Mat mat = QImageToMat(image);
cv::imwrite("./mat_t2.jpg", mat);
ui->label_1->setPixmap(pixOrg);
}
}
void QImageToMatDialog::slotMatToQImage()
{
cv::Mat mat = cv::imread("./t3.jpg");
QImage image = matToQImage(mat);
QPixmap pix2 = QPixmap::fromImage(image);
pix2 = pix2.scaled(400, 300);
ui->label_2->setPixmap(pix2);
}
参考:
https://www.cnblogs.com/ybqjymy/p/13595616.html
https://blog.csdn.net/amnesiagreen/article/details/10735
https://blog.csdn.net/liyuanbhu/article/details/46659725
推荐内容
阅读全文
AI总结




OpenCV: 开源计算机视觉库
最近提交(Master分支:7 个月前 )
6ef57463
Migrated IPP impl for flip and transpose to HAL 1 天前
c1d71d53
imgproc: disable SIMD for compareHist(INTERSECT) if f64 is unsupported #27220
Close https://github.com/opencv/opencv/issues/24757
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
1 天前
更多推荐
相关推荐
查看更多
opencv

OpenCV: 开源计算机视觉库
opencv

opencv

R bindings for OpenCV
热门开源项目
活动日历
查看更多
直播时间 2025-04-09 14:34:18

樱花限定季|G-Star校园行&华中师范大学专场
直播时间 2025-04-07 14:51:20

樱花限定季|G-Star校园行&华中农业大学专场
直播时间 2025-03-26 14:30:09

开源工业物联实战!
直播时间 2025-03-25 14:30:17

Heygem.ai数字人超4000颗星火燎原!
直播时间 2025-03-13 18:32:35

全栈自研企业级AI平台:Java核心技术×私有化部署实战
所有评论(0)