#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <QtGui>
//make QImage point to the contents of cv::Mat
inline QImage const mat_to_qimage_ref(cv::Mat &mat)
{
return QImage((unsigned char*)(mat.data), mat.cols, mat.rows, mat.step1(), QImage::Format_RGB32);
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QImage img("lena2.jpg");
cv::Mat mat(img.height(), img.width(), CV_8UC4, img.bits(), img.bytesPerLine());
QImage img = mat_to_qimage_ref(mat); //#1
//QImage img2((unsigned char*)(mat.data), mat.cols, mat.rows, mat.step, QImage::Format_RGB32); #2
QLabel label;
label.setPixmap(QPixmap::fromImage(img)); //crash at here
label.show();
return a.exec();
}
(#2)没关系,但是#1会出现未定义的行为吗?(我的情况是崩溃)
此外,如果您将其用作下面的代码,那就没关系
cv::Mat img = cv::imread("lena2.jpg");
QLabel label;
label.setPixmap(QPixmap::fromImage(mat_to_qimage_ref(img)));
label.show();
不知道发生了什么,与循环依赖有关的事情?
答案 0 :(得分:1)
你的功能应该是这样的:
QImage mat_to_qimage_ref(const cv::Mat3b &src) {
QImage dest(src.cols, src.rows, QImage::Format_ARGB32);
for (int y = 0; y < src.rows; ++y) {
const cv::Vec3b *srcrow = src[y];
QRgb *destrow = (QRgb*)dest.scanLine(y);
for (int x = 0; x < src.cols; ++x) {
destrow[x] = qRgba(srcrow[x][2], srcrow[x][1], srcrow[x][0], 255);
}
}
return dest;
}
答案 1 :(得分:1)
如果您不想复制图像数据,只需为数据创建新的QImage标题,请尝试以下操作:
Mat mat = Mat(...);
QImage qImage = QImage(
(const uchar*)(mat.data),
mat.cols,
mat.rows,
mat.step1(),
QImage::Format_ARGB32); // if you have no alpha channel (CV_8UC3),
// you can use Format_RGB888
另请注意,OpenCV通常使用BGR通道顺序,您可以使用rgbSwapped()来解决此问题,但我不知道是否通过此函数调用复制了数据。