Graphics 版 (精华区)

发信人: zjliu (秋天的萝卜), 信区: Graphics
标  题: VC编程实现灰度图像与彩色图像的相互转换ZZ
发信站: 哈工大紫丁香 (Sun Nov 16 20:28:39 2003), 站内信件

PhotoShop的图像处理功能很强,其中有一个功能是将灰度图像转换为彩色图像,数字图

像处理中,也经常要遇到灰度图像与彩色图像相互转换的问题,如何自己解决这个问题

,值得大家探讨,现将我解决这类问题的方法陈述如下:
  工程应用中经常要遇到需要把彩色图像到灰度图像的变换的问题,采集卡过来的图

像为彩色图像,为加快处理速度,要把彩色图像转换为黑白图象,这个问题比较好解决

,一般情况下彩色图像每个像素用三个字节表示,每个字节对应着R、G、B分量的亮度(

红、绿、蓝),转换后的黑白图像的一个像素用一个字节表示该点的灰度值,它的值在

0~255之间,数值越大,该点越白,既越亮,越小则越黑。转换公式为Gray(i,j)=0.11*

R(i,j)+0.59*G(i,j)+0.3*B(i,j),其中Gray(i,j)为转换后的黑白图像在(i,j)点处的

灰度值,我们可以观察该式,其中绿色所占的比重最大,所以转换时可以直接使用G值作

为转换后的灰度。
  至于灰度图像转换为彩色图像,技术上称为灰度图像的伪彩色处理,这是一种视觉

效果明显而技术又不是很复杂的图像增强技术。灰度图像中,如果相邻像素点的灰度相

差不大,但包含了丰富的信息的话,人眼则无法从图像中提取相应的信息,因为人眼分

辨灰度的能力很差,一般只有几十个数量级,但是人眼对彩色信号的分辨率却很强,这

样将黑白图像转换为彩色图像人眼可以提取更多的信息量。在转换过程中,经常采用的

技术是灰度级-彩色变换,意思就是对黑白图像上的每一个像素点,取得该点的灰度值并

送入三个通道经过实施不同的变换,产生相应的R、G、B的亮度值,即所求彩色图像对应

像素点的彩色值,具体变换公式很多,我采用的是最常用的一种,变换曲线图如下:
  上图中,三个图分别代表了三个变换通道,R、G、B指的是变换后对应点的R、G、B

分量值,L指的是各个分量的最大值为255,G(x,y)为相应点的灰度值。理论上就这些

,下面是我用VC实现的源代码,图一为我的灰度位图,图二为伪彩色处理后的结果图。

我这个实现函数中是如何得到灰度位图的数据的就不多讲了,有兴趣的朋友可参考我在

天极网上九月十号发表的《VC灰度位图处理》一文,那里应该讲的很清楚了。需要读者

注意的是彩色图像中每个象素中的三个字节分别代表的分量,第一个字节为B,第二个为

G值、最后一个为R值,这个顺序不要搞错了。代码实现如下:
VC编程实现灰度图像与彩色图像的相互转换
void CDibView::OnMenuchange() file://图像转换实现函数
{
 // TODO: Add your command handler code here
 HANDLE data1handle;
 LPBITMAPINFOHEADER lpBi;
 BITMAPINFO *m_pBMI;
 CDibDoc *pDoc=GetDocument();
 HDIB hdib;
 unsigned char *hData;
 unsigned char *data;
 hdib=pDoc->GetHDIB();//得到位图数据的句柄,其中包含图像信息头
 BeginWaitCursor();
 lpBi=(LPBITMAPINFOHEADER)GlobalLock((HGLOBAL)hdib);
 hData=(unsigned char*)FindDIBBits((LPSTR)lpBi);
 m_pBMI=new BITMAPINFO;//生成彩色图像的信息头
 m_pBMI->bmiHeader.biBitCount=24;
 m_pBMI->bmiHeader.biClrImportant=0;
 m_pBMI->bmiHeader.biClrUsed=0;
 m_pBMI->bmiHeader.biCompression=BI_RGB;
 m_pBMI->bmiHeader.biHeight=lpBi->biHeight;
 m_pBMI->bmiHeader.biWidth=lpBi->biWidth;
 m_pBMI->bmiHeader.biPlanes=1;
 m_pBMI->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
 m_pBMI->bmiHeader.biXPelsPerMeter=0;
 m_pBMI->bmiHeader.biYPelsPerMeter=0;
 m_pBMI->bmiHeader.biSizeImage=WIDTHBYTES(lpBi->biWidth*8)*lpBi->biHeight*3

;
 file://data=hData;
 int R,G,B,i,j;
 data1handle=GlobalAlloc(GMEM_SHARE,WIDTHBYTES(lpBi->biWidth*8)*lpBi->biHei

ght*3);
 file://生成存储彩色图象数据的缓冲区
 data=(unsigned char*)GlobalLock((HGLOBAL)data1handle);
 for(i=0;ibiHeight;i++)//实现灰度到彩色变换
  for(j=0;jbiWidth*8);j++)
  {
   if(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)<=64)
   {R=0;
    G=(int)4*(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j));
    B=255;
   }
   if(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)>64
    && *(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)<=128)
    {R=0;
     G=255;
     B=(int)4*(128-*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j));
    }
   if(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)>128
     && *(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)<=192)
     {R=(int)4*(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)-128);
      G=255;
      B=0;
     }
   if(*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)>192
     && *(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j)<=255)
     {R=255;
      G=(int)4*(255-*(hData+i*WIDTHBYTES(lpBi->biWidth*8)+j));
      B=0;
     }
   file://将生成的R、G、B分量存入目标缓冲区
   *(data+i*WIDTHBYTES(lpBi->biWidth*8)*3+j*3)=B;
   *(data+i*WIDTHBYTES(lpBi->biWidth*8)*3+j*3+1)=G;
   *(data+i*WIDTHBYTES(lpBi->biWidth*8)*3+j*3+2)=R;
  }
  GlobalUnlock((HGLOBAL)hdib);
  GlobalUnlock(data1handle);
  EndWaitCursor();
  CClientDC pDC(this);
  file://显示真彩色图像
  StretchDIBits(pDC.GetSafeHdc(),0,0,lpBi->biWidth,lpBi->biHeight,0,0,
         lpBi->biWidth, lpBi->biHeight,data,m_pBMI,DIB_RGB_COLORS,
         SRCCOPY);
  delete m_pBMI;
 


--
╔═══════════════════╗
║★★★★★友谊第一  比赛第二★★★★★║
╚═══════════════════╝


※ 来源:.哈工大紫丁香 bbs.hit.edu.cn [FROM: 202.118.229.162]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:2.430毫秒