频道栏目
首页 > 资讯 > 其他综合 > 正文

QImage与cv::Mat之间的相互转换

17-01-19        来源:[db:作者]  
收藏   我要投稿
QImage与cv::Mat 之间的相互转换:最近做图像处理方面的项目比较多,很多算法自己从头写的话太浪费时间,而且自己写的也不一定完善,早就听说OpenCV在图像处理算法方面功能很强大,一直没时间学习,这次正好项目用到了,临时抱佛脚学习些OpenCV入门知识。因为我的程序界面都是用Qt写的,因此也花了点时间研究了如何将OpenCV和Qt融合在一起,协同工作。

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();

}
相关TAG标签
上一篇:小程序之地图周边
下一篇:根据百度API获得经纬度 然后根据经纬度在获得城市信息
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站