VS+QT+OpenCV图像处理输出

来源:互联网 发布:第三方软件是什么意思 编辑:程序博客网 时间:2024/04/29 00:26

在使用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
  1. QImage MatToQImage(const cv::Mat& mat)    
  2. {    
  3.     // 8-bits unsigned, NO. OF CHANNELS = 1    
  4.     if(mat.type() == CV_8UC1)    
  5.     {    
  6.         QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);    
  7.         // Set the color table (used to translate colour indexes to qRgb values)    
  8.         image.setColorCount(256);    
  9.         for(int i = 0; i < 256; i++)    
  10.         {    
  11.             image.setColor(i, qRgb(i, i, i));    
  12.         }    
  13.         // Copy input Mat    
  14.         uchar *pSrc = mat.data;    
  15.         for(int row = 0; row < mat.rows; row ++)    
  16.         {    
  17.             uchar *pDest = image.scanLine(row);    
  18.             memcpy(pDest, pSrc, mat.cols);    
  19.             pSrc += mat.step;    
  20.         }    
  21.         return image;    
  22.     }    
  23.     // 8-bits unsigned, NO. OF CHANNELS = 3    
  24.     else if(mat.type() == CV_8UC3)    
  25.     {    
  26.         // Copy input Mat    
  27.         const uchar *pSrc = (const uchar*)mat.data;    
  28.         // Create QImage with same dimensions as input Mat    
  29.         QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);    
  30.         return image.rgbSwapped();    
  31.     }    
  32.     else if(mat.type() == CV_8UC4)    
  33.     {    
  34.         qDebug() << "CV_8UC4";    
  35.         // Copy input Mat    
  36.         const uchar *pSrc = (const uchar*)mat.data;    
  37.         // Create QImage with same dimensions as input Mat    
  38.         QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);    
  39.         return image.copy();    
  40.     }    
  41.     else    
  42.     {    
  43.         qDebug() << "ERROR: Mat could not be converted to QImage.";    
  44.         return QImage();    
  45.     }    
  46. }

[cpp] view plain copy
  1. cv::Mat QImageToMat(QImage image)  
  2. {  
  3.     cv::Mat mat;  
  4.     switch (image.format())  
  5.     {  
  6.     case QImage::Format_ARGB32:  
  7.     case QImage::Format_RGB32:  
  8.     case QImage::Format_ARGB32_Premultiplied:  
  9.         mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());  
  10.         break;  
  11.     case QImage::Format_RGB888:  
  12.         mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine());  
  13.         cv::cvtColor(mat, mat, CV_BGR2RGB);  
  14.         break;  
  15.     case QImage::Format_Indexed8:  
  16.         mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());  
  17.         break;  
  18.     }  
  19.     return mat;  
  20. }  

在图片格式转换完成后,使用
ui.QLabel->setPixmap(QPixmap::fromImage(QImage));
ui.QLabel->resize(ui.QLabel->pixmap()->size());
完成QImage输出到QLabel的操作

本文代码片段来源:http://blog.csdn.net/dancing_night/article/details/51545524,如有侵犯,请联系本人好及时删除。