Qt 中彩色图像转换为灰度图

http://blog.csdn.net/liyuanbhu/article/details/46659725


最近在做几个图像处理相关的项目。里面有一个操作就是需要先将彩色图像转换为灰度图像。QImage 有一个convertToFormat方法。最开始一直用这个函数来实现。但是今天仔细看了看,发现这个函数转换出的灰度图与原始图像的亮度似乎是有区别的。比如说下面这副图像:

Qt 中彩色图像转换为灰度图_第1张图片


用下面这三行代码转换:

[cpp]  view plain  copy
  1. QImage image2 = image.convertToFormat(QImage::Format_Indexed8);  
  2.     image2.setColorCount(256);  
  3.     for(int i = 0; i < 256; i++)  
  4.     {  
  5.         image2.setColor(i, qRgb(i, i, i));  
  6. }  

得到的结果是这样的:

Qt 中彩色图像转换为灰度图_第2张图片

明显转换之后的图像要暗一些,对比度也差很多。说明这个方法是错误的。其实想想也能知道,convertToFormat 只是选取了原始图像中出现最多的那些颜色,并以此生成了colorTable。这个colorTable 的顺序与亮度其实不一定具有线性关系,我这样随意的转换从原理上就是说不通的。

 

后来花了点时间,自己写了个转换代码:

[cpp]  view plain  copy
  1. QImage toGray( QImage image )  
  2. {  
  3.     int height = image.height();  
  4.     int width = image.width();  
  5.     QImage ret(width, height, QImage::Format_Indexed8);  
  6.     ret.setColorCount(256);  
  7.     for(int i = 0; i < 256; i++)  
  8.     {  
  9.         ret.setColor(i, qRgb(i, i, i));  
  10.     }  
  11.     switch(image.format())  
  12.     {  
  13.     case QImage::Format_Indexed8:  
  14.         for(int i = 0; i < height; i ++)  
  15.         {  
  16.             const uchar *pSrc = (uchar *)image.constScanLine(i);  
  17.             uchar *pDest = (uchar *)ret.scanLine(i);  
  18.             memcpy(pDest, pSrc, width);  
  19.         }  
  20.         break;  
  21.     case QImage::Format_RGB32:  
  22.     case QImage::Format_ARGB32:  
  23.     case QImage::Format_ARGB32_Premultiplied:  
  24.         for(int i = 0; i < height; i ++)  
  25.         {  
  26.             const QRgb *pSrc = (QRgb *)image.constScanLine(i);  
  27.             uchar *pDest = (uchar *)ret.scanLine(i);  
  28. //QRgb *pDest = (QRgb*)image.scanLine(i); 
  29.             forint j = 0; j < width; j ++)  
  30.             {  
  31.                  pDest[j] = qGray(pSrc[j]);  
  32. //((unsigned char*)&pDest[j])[3] = 56;
  33.             }  
  34.         }  
  35.         break;  
  36.     }  
  37.     return ret;  
  38. }  

利用这个代码的转换结果如下:

Qt 中彩色图像转换为灰度图_第3张图片

这个的转换效果明显要好很多。看来写代码还是要精益求精,不能凑合着来啊。


你可能感兴趣的:(图像处理)