Qt中处理图像主要用的是QImage类,OpenCV中主要用的是cv::Mat类。下面的两个函数可以用来实现这两个类相互转换。
QImagecvMat2QImage(constcv::Mat&mat) { //8-bitsunsigned,NO.OFCHANNELS=1 if(mat.type()==CV_8UC1) { QImageimage(mat.cols,mat.rows,QImage::Format_Indexed8); //Setthecolortable(usedtotranslatecolourindexestoqRgbvalues) image.setColorCount(256); for(inti=0;i<256;i++) { image.setColor(i,qRgb(i,i,i)); } //CopyinputMat uchar*pSrc=mat.data; for(introw=0;row { uchar*pDest=image.scanLine(row); memcpy(pDest,pSrc,mat.cols); pSrc+=mat.step; } returnimage; } //8-bitsunsigned,NO.OFCHANNELS=3 elseif(mat.type()==CV_8UC3) { //CopyinputMat constuchar*pSrc=(constuchar*)mat.data; //CreateQImagewithsamedimensionsasinputMat QImageimage(pSrc,mat.cols,mat.rows,mat.step,QImage::Format_RGB888); returnimage.rgbSwapped(); } elseif(mat.type()==CV_8UC4) { qDebug()<<"CV_8UC4"; //CopyinputMat constuchar*pSrc=(constuchar*)mat.data; //CreateQImagewithsamedimensionsasinputMat QImageimage(pSrc,mat.cols,mat.rows,mat.step,QImage::Format_ARGB32); returnimage.copy(); } else { qDebug()<<"ERROR:MatcouldnotbeconvertedtoQImage."; returnQImage(); } } cv::MatQImage2cvMat(QImageimage) { cv::Matmat; qDebug()< switch(image.format()) { caseQImage::Format_ARGB32: caseQImage::Format_RGB32: caseQImage::Format_ARGB32_Premultiplied: mat=cv::Mat(image.height(),image.width(),CV_8UC4,(void*)image.constBits(),image.bytesPerLine()); break; caseQImage::Format_RGB888: mat=cv::Mat(image.height(),image.width(),CV_8UC3,(void*)image.constBits(),image.bytesPerLine()); cv::cvtColor(mat,mat,CV_BGR2RGB); break; caseQImage::Format_Indexed8: mat=cv::Mat(image.height(),image.width(),CV_8UC1,(void*)image.constBits(),image.bytesPerLine()); break; } returnmat; }
程序比较简单,就不多说明了。唯一需要注意的是cvMat 和QImage 对于RGBA 这四个分量的排列顺序是不相同的。转换的时候需要调换一下。但是Qt 的文档中说的很明确,QImage内部数据存储的方式不能保证以后永远不变。所以这个代码也不能保证一直是可用的。
下面是五个测试用例。基本上把各种常见情况都覆盖了。
voidtest1() { cv::Matmat=cv::imread("Q:\\Koala.jpg",cv::IMREAD_UNCHANGED); cv::cvtColor(mat,mat,CV_BGR2BGRA); QImageimage=cvMat2QImage(mat); qDebug()<<(mat.type()==CV_8UC4); cvNamedWindow("cvMat2QImageRGB32",CV_WINDOW_AUTOSIZE); imshow("cvMat2QImageRGB32",mat); QLabellabel; label.setPixmap(QPixmap::fromImage(image)); label.show(); cv::waitKey(10000); } voidtest2() { cv::Matmat=cv::imread("Q:\\Koala.jpg",cv::IMREAD_UNCHANGED); cv::cvtColor(mat,mat,CV_BGR2GRAY); QImageimage=cvMat2QImage(mat); cvNamedWindow("cvMat2QImagegray",CV_WINDOW_AUTOSIZE); imshow("cvMat2QImagegray",mat); QLabellabel; label.setPixmap(QPixmap::fromImage(image)); label.show(); cv::waitKey(10000); } voidtest3() { QImageimage("Q:\\Koala.jpg"); image=image.convertToFormat(QImage::Format_RGB32); cv::Matmat=QImage2cvMat(image); //cv::cvtColor(mat,mat,CV_BGR2RGB); imshow("QImage2cvMatRGB32",mat); cv::waitKey(10000); } voidtest4() { QImageimage("Q:\\Koala.jpg"); image=image.convertToFormat(QImage::Format_RGB888); cv::Matmat=QImage2cvMat(image); imshow("QImage2cvMatRGB24",mat); cv::waitKey(10000); } voidtest5() { QImageimage("Q:\\Koala.jpg"); image=image.convertToFormat(QImage::Format_Indexed8); cv::Matmat=QImage2cvMat(image); imshow("QImage2cvMatIndexed8",mat); cv::waitKey(10000); } intmain(intargc,char*argv[]) { QApplicationa(argc,argv); //test1(); //test2(); //test3(); //test4(); //test5(); test1(); returna.exec(); }