//抱歉我的英语不好。
请告诉我,我做错了什么? 我已经阅读了很多资料并编写了一些代码,但是结果很糟糕。
据我理解,在OpenCV中,CV_8UC3与QImage :: Format_RGB888相同,只是BGR和RGB不同。
要以这种格式读取cv :: Mat
,可以执行以下操作:
cv::Mat mat1 = cv::imread("bugero.jpg",3);
所以,要将cv::Mat转换为QImage,我可以这样做:
QImage Mat2QImage(cv::Mat const& src)
{
cv::Mat temp(src.cols,src.rows,src.type());
cvtColor(src, temp,CV_BGR2RGB);
QImage dest= QImage((uchar*) temp.data, temp.cols, temp.rows, temp.step, QImage::Format_RGB888);
return dest;
}
我创建了一个临时mat,因为我想在QImage中拥有数据的副本。
然后,要把它转换回来,我必须执行:
cv::Mat QImage2Mat(QImage const& src)
{
QImage temp = src.copy();
cv::Mat res(temp.height(),temp.width(),CV_8UC3,(uchar*)temp.bits(),temp.bytesPerLine());
cvtColor(res, res,CV_BGR2RGB);
return res;
}
我已经插入了cvtColor(res, res, CV_BGR2RGB);来使得OpenCV的Mat对象使用BGR颜色。我不确切知道这个函数cvtColor(res, res, CV_BGR2RGB);内部发生了什么,但我决定如果cvtColor(res, res, CV_BGR2RGB);交换了红色和蓝色的位置,那么它会将颜色位置恢复,因为我没有找到CV_BGR2RGB。
因此,我编写了一个短的示例程序。
#include <QApplication>
#include <QtGui>
#include <cv.h>
#include "opencv2/highgui/highgui.hpp"
QImage Mat2QImage(cv::Mat const& src)
{
cv::Mat temp(src.cols,src.rows,src.type()); // make the same cv::Mat
cvtColor(src, temp,CV_BGR2RGB); // cvtColor Makes a copt, that what i need
QImage dest= QImage((uchar*) temp.data, temp.cols, temp.rows, temp.step, QImage::Format_RGB888);
return dest;
}
cv::Mat QImage2Mat(QImage const& src)
{
QImage temp = src.copy();
cv::Mat res(temp.height(),temp.width(),CV_8UC3,(uchar*)temp.bits(),temp.bytesPerLine());
cvtColor(res, res,CV_BGR2RGB); // make convert colort to BGR !
return res;
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget W1;
QWidget W2;
QLabel imlab1(&W1);
QLabel imlab2(&W2);
W1.setWindowTitle("Convert cv::Mat to QImage First time");
W2.setWindowTitle("Convert cv::Mat to QImage Second time");
cv::Mat mat1 = cv::imread("bugero.jpg",3);
QImage qim1 = Mat2QImage(mat1);
cv::Mat mat2 = QImage2Mat(qim1);
QImage qim2 = Mat2QImage(mat2);
cv::Mat mat3 = QImage2Mat(qim2);
cv::imshow("First Mat",mat1);
imlab1.setPixmap(QPixmap::fromImage(qim1));
W1.setFixedSize(qim1.size());
cv::imshow("Convert QImage to cv::Mat firstly",mat2);
imlab2.setPixmap(QPixmap::fromImage(qim2));
W2.setFixedSize(qim2.size());
cv::imshow("Convert QImage to cv::Mat secondly",mat2);
W1.show();
W2.show();
return a.exec();
}
和 .pro 文件
INCLUDEPATH += /usr/local/include/opencv /usr/local/include/opencv2
LIBS += -lopencv_core -lopencv_imgproc\
-lopencv_highgui
QT += gui
QT += core
SOURCES += \
QcvMat.cpp \
我得到了一个糟糕的结果!!!
有没有人可以帮忙吗?
为了获取cv :: Mat.step和QImage.bytesPerLine()的调试信息,我添加了一些调试信息,并且它们是不同的。
alex@lenovo /media/Files/Programming/Cpp/tests/QImagecvMat $ ./QcvMat
cv step 942
QImage bytesPerLine 944
cv step 942
QImage bytesPerLine 944
这是什么意思,可能存在问题吗?
dest.detach()
并返回dest
?另外,为什么detach()
没有在文档中提到呢?不管怎样,这个解决方案使用了 Qt 的rgbSwapped()
函数,该函数已经被记录和证明有效。 - takfuruyaCV_8UC1
情况(内存未分离)。由于它与cvMatToQPixmap
一起使用并且这会复制内容,因此它没有被暴露出来。关于这个detach
,我没有注意到它没有被记录。所以我会修复这个问题。 - Marek RQImage2Mat
时,我们应该传递QImage的引用还是直接传递变量? - arqam