QImage和IplImage转换总结

Posted yzl050819

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QImage和IplImage转换总结相关的知识,希望对你有一定的参考价值。

在arm中做图像处理,因为不支持GTK,一般都会用到QT来实现显示功能,所以不可避免的要涉及到QImage和IplImage两种图像格式之间的转换,下面总结一下转换的方法。

(下面格式转换的代码都是网友写的,我这里只是归纳修改了一下)

IplImage 转换为 QImage

 

方法1 

[plain] view plain copy
 
  1. QImage *IplImageToQImage(const IplImage *img)  
  2. {  
  3.     QImage *qmg;  
  4.     cvCvtColor(img,img,CV_BGR2RGB);  
  5.     qmg = new QImage((unsigned char*)img->imageData,img->width,img->height,img->widthStep,QImage::Format_RGB888);  
  6.     return qmg;  
  7. }  

这里要注意的是,IplImage每个像素点存储的格式为BGR,而QImage每个像素点存储的格式为RGB,所以在转换之前需要先使用opencv提供的cvCvtColor函数将BGR图像变为RGB图像。还有就是QImage最后一个参数QImage::Format_RGB888,这是指色彩空间R,G,B三个通道分别用8位来表示,如果是灰度图,则参数为QImage::Format_Indexed8。

例如:

 

[plain] view plain copy
 
  1. QImage *IplImageToQImage(const IplImage *img)  
  2. {  
  3.     QImage *qmg;  
  4.     IplImage *img_gray = cvCreateImage(cvGetSize(img),8,1);  
  5.     cvCvtColor(img,img_gray,CV_BGR2GRAY);  
  6.     qmg = new QImage((unsigned char*)img->imageData,img->width,img->height,img->widthStep,QImage::Format_Indexed8);  
  7.     return qmg;  
  8. }  

 

方法2

[plain] view plain copy
 
  1. QImage *IplImageToQImage(*img)  
  2. {  
  3.     QImage *qmg = new QImage (img->width,img-height,img->widthStep,QImage::Format_RGB32);  
  4.     for (int i=0; i<height; ++i)  
  5.     {  
  6.         for (int j=0; j<width; ++j)  
  7.         {  
  8.            int r,g,b;  
  9.            if( 3 == img->nChannels )  
  10.            {  
  11.                 b = (int)CV_IMAGE_ELEM( img, uchar, i, j*3+0 );  
  12.             g = (int)CV_IMAGE_ELEM( img, uchar, i, j*3+1 );  
  13.             r = (int)CV_IMAGE_ELEM( img, uchar, i, j*3+2 );  
  14.             }  
  15.         else if( 1 == img->nChannels )  
  16.         {  
  17.             b = (int)CV_IMAGE_ELEM( img, uchar, i, j*3+0 );  
  18.         g = b;  
  19.             r = b;  
  20.              }  
  21.                qmg->setPixel( j, i, qRgb(r,g,b) );  
  22.          }  
  23.     }  
  24.     return qmg;  
  25. }  


这里要注意的是qmg->setPixel( j, i, qRgb(r,g,b) );括号里面是(j,i);而不是(i,j)。我还没弄明白为什么这里要调换一下i,j的顺序,希望知道的朋友指点一下。

QImage转换为IplImage

方法1

[plain] view plain copy
 
  1. IplImage *QImageToIplImage(const QImage * qImage)  
  2. {  
  3.     int width = qImage->width();  
  4.     int height = qImage->height();  
  5.     CvSize Size;  
  6.     Size.height = height;  
  7.     Size.width = width;  
  8.     IplImage *IplImageBuffer = cvCreateImage(Size, IPL_DEPTH_8U, 3);  
  9.     for (int y = 0; y < height; ++y)  
  10.     {  
  11.         for (int x = 0; x < width; ++x)  
  12.         {  
  13.             QRgb rgb = qImage->pixel(x, y);  
  14.             cvSet2D(IplImageBuffer, y, x, CV_RGB(qRed(rgb), qGreen(rgb), qBlue(rgb)));  
  15.         }  
  16.     }  
  17.     return IplImageBuffer;  
  18. }  


 

方法2

 

[plain] view plain copy
 
  1. IplImage *QImageToIplImage(const QImage * qImage)  
  2. {  
  3.     int width = qImage->width();  
  4.     int height = qImage->height();  
  5.     CvSize Size;  
  6.     Size.height = height;  
  7.     Size.width = width;  
  8.     IplImage *IplImageBuffer = cvCreateImage(Size, IPL_DEPTH_8U, 3);  
  9.     for (int y = 0; y < height; ++y)  
  10.     {  
  11.         for (int x = 0; x < width; ++x)  
  12.         {  
  13.             QRgb rgb = qImage->pixel(x, y);  
  14.             CV_IMAGE_ELEM( IplImageBuffer, uchar, y, x*3+0 ) = qBlue(rgb);  
  15.         CV_IMAGE_ELEM( IplImageBuffer, uchar, y, x*3+1 ) = qGreen(rgb);  
  16.         CV_IMAGE_ELEM( IplImageBuffer, uchar, y, x*3+2 ) = qRed(rgb);  
  17.     }   
  18.      }  
  19.      return IplImageBuffer;  
  20. }  


这两种方法其实都是一样的,只是表达形式有点不同,还有就是一个是生成RGB格式图像,一个是生成BGR格式的图像。

以上是关于QImage和IplImage转换总结的主要内容,如果未能解决你的问题,请参考以下文章

从内存缓冲区保存 QImage

Opencv和Qt QImage格式转Mat

Convert between cv::Mat and QImage 两种图片类转换

Convert between cv::Mat and QImage 两种图片类转换

Qimage 到 cv::Mat 转换的奇怪行为

使用 OpenMP 进行并行 IplImage 转换