在使用VS+QT+OpenCV做图像处理的过程中,对OpenCV中的Mat类型的数据格式一直很头疼CV_8UC4,CV_32F等等格式的输出如果是在使用namewindow+imshow的组合进行弹窗输出时确实是没有什么大问题,但是当需要把图片转成QImage输出到控件上时就会出大问题了,因为不同图片格式的Mat在转成QImage时需要使用不同的参数。
但是好在Mat类型在自身的不同格式间转换时没有什么阻碍的。所以就此整理出以下Mat类型输出到QT控件的方法。
一、输出灰度图像,输出灰度图像在格式转换前后通常来说不会有太大的影响,仅有的影响也就只有因为QImage可能会只显示图片的左上角某一部分(长三分之一,宽三分之一),在我看来应该是图像中每个像素数据所占的位数不一样导致的。所以通常只需要在转成QImage前把图片使用mat.convertTo(mat,CV_8UC3){也可以用其他格式}转换格式后再转成QImage(转成QImage的方法在下面会给出)。
二、输出RGB图,输出RGB图在通常时和输出灰度图是一样的(这个通常情况指的是读取的是RGB图,输出这个读取的RGB图),但是如果对RGB图进行了三个通道的拆分后,对RGB通道分别处理以后再重新合成RGB图像的话(使用vector<Mat> vmat读取B G R三个通道的数据并分别处理,最后使用merge(vmat,mat)组成输出的图像),需要在merge后再次使用convertTO转变mat的格式,然后才能统一输出,至于转成什么格式,推荐是CV_8UC1,CV_8UC3,CV_8UC4,原因的话,因为本人对QImage的数据格式不了解,只能参照其他博主的QImage和Mat类型的格式转换方法,在之前搜索的资料中看到过两个博主的代码是可用的,根据自己的使用体验推荐下面这段代码
[cpp] view plain copy
- QImage MatToQImage(const cv::Mat& mat)
- {
- // 8-bits unsigned, NO. OF CHANNELS = 1
- if(mat.type() == CV_8UC1)
- {
- QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
- // Set the color table (used to translate colour indexes to qRgb values)
- image.setColorCount(256);
- for(int i = 0; i < 256; i++)
- {
- image.setColor(i, qRgb(i, i, i));
- }
- // Copy input Mat
- uchar *pSrc = mat.data;
- for(int row = 0; row < mat.rows; row ++)
- {
- uchar *pDest = image.scanLine(row);
- memcpy(pDest, pSrc, mat.cols);
- pSrc += mat.step;
- }
- return image;
- }
- // 8-bits unsigned, NO. OF CHANNELS = 3
- else if(mat.type() == CV_8UC3)
- {
- // Copy input Mat
- const uchar *pSrc = (const uchar*)mat.data;
- // Create QImage with same dimensions as input Mat
- QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
- return image.rgbSwapped();
- }
- else if(mat.type() == CV_8UC4)
- {
- qDebug() << "CV_8UC4";
- // Copy input Mat
- const uchar *pSrc = (const uchar*)mat.data;
- // Create QImage with same dimensions as input Mat
- QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
- return image.copy();
- }
- else
- {
- qDebug() << "ERROR: Mat could not be converted to QImage.";
- return QImage();
- }
- }
[cpp] view plain copy
- cv::Mat QImageToMat(QImage image)
- {
- cv::Mat mat;
- switch (image.format())
- {
- case QImage::Format_ARGB32:
- case QImage::Format_RGB32:
- case QImage::Format_ARGB32_Premultiplied:
- mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());
- break;
- case QImage::Format_RGB888:
- mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine());
- cv::cvtColor(mat, mat, CV_BGR2RGB);
- break;
- case QImage::Format_Indexed8:
- mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());
- break;
- }
- return mat;
- }
在图片格式转换完成后,使用
ui.QLabel->setPixmap(QPixmap::fromImage(QImage));
ui.QLabel->resize(ui.QLabel->pixmap()->size());
完成QImage输出到QLabel的操作
本文代码片段来源:http://blog.csdn.net/dancing_night/article/details/51545524,如有侵犯,请联系本人好及时删除。