图像的灰度化原理和实现

http://blog.csdn.net/hnney/archive/2009/05/18/4194408.aspx

图像的灰度化原理和实现

将彩色图像转化成为灰度图像的过程成为图像的灰度化处理 。彩色图像中的每个像素的颜色有R、G、B三个分量决定,而每个分量有255中值可取,这样一个像素点可以有1600多万(255*255*255)的颜色的变化范围。而灰度图像是R、G、B三个分量相同的一种特殊的彩色图像 ,其一个像素点的变化范围为255种,所以在数字图像处理种一般先将各种格式的图像转变成灰度图像以使后续的图像的计算量变得少一些灰度图像的描述与彩色图像一样仍然反映了整幅图像的整体和局部的色度和亮度等级的分布和特征 。图像的灰度化处理可用两种方法来实现。

第一种方法使求出每个像素点的R、G、B三个分量的平均值,然后将这个平均值赋予给这个像素的三个分量。

第二种方法是根据YUV的颜色空间中,Y的分量的物理意义是点的亮度,由该值反映亮度等级,根据RGB和YUV颜色空间的变化关系可建立亮度Y与R、G、B三个颜色分量的对应:Y=0.3R+0.59G+0.11B ,以这个亮度值表达图像的灰度值。

 

// c++ 实现代码

BOOL RGBToGray(BYTE *pData,int iWidth,int iHeight,int iDepth)
{
    BYTE red,green,blue;
    BYTE grey;

    if(iDepth != 3 && iDepth != 4)
    {
        return FALSE;
    }
   
    for(int j=0;j < iHeight;j++)
    {
        for(int i=0;i < iWidth;i++)
        {
            blue = *(pData + j*iWidth*iDepth+i*iDepth);
            green = *(pData + j*iWidth*iDepth+i*iDepth + 1);
            red = *(pData + j*iWidth*iDepth+i*iDepth + 2);

            grey = (BYTE)((float)(red*0.299+green*0.587+blue*0.114));
           
            // 转换后 RGB三个分量的值相等
            *(pData + j*iWidth*iDepth+i*iDepth) = grey;
            *(pData + j*iWidth*iDepth+i*iDepth + 1) = grey;
            *(pData + j*iWidth*iDepth+i*iDepth + 2) = grey;
        }
    }

    return TRUE;
}

 

 

// 256色bmp转灰度图代码

/****************************************************************
* 函数名称:
*      Convert256toGray()
*
* 参数:
*     HDIB hDIB     -图像的句柄
*
*  返回值:
*        无
*
*  功能:
*     将256色位图转化为灰度图
*
***************************************************************/
void Convert256toGray(HDIB hDIB)
{
    LPSTR    lpDIB;   
    // 由DIB句柄得到DIB指针并锁定DIB
    lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)hDIB);   
    // 指向DIB象素数据区的指针
    LPSTR   lpDIBBits;   
    // 指向DIB象素的指针
    BYTE *    lpSrc;   
    // 图像宽度
    LONG    lWidth;   
    // 图像高度
    LONG      lHeight;
    // 图像每行的字节数
    LONG    lLineBytes;   
    // 指向BITMAPINFO结构的指针(Win3.0)
    LPBITMAPINFO lpbmi;   
    // 指向BITMAPCOREINFO结构的指针
    LPBITMAPCOREINFO lpbmc;   
    // 获取指向BITMAPINFO结构的指针(Win3.0)
    lpbmi = (LPBITMAPINFO)lpDIB;
    // 获取指向BITMAPCOREINFO结构的指针
    lpbmc = (LPBITMAPCOREINFO)lpDIB;   

    // 灰度映射表
    BYTE bMap[256];
   
    // 计算灰度映射表(保存各个颜色的灰度值),并更新DIB调色板
    int    i,j;
    for (i = 0; i < 256; i ++)
    {
        // 计算该颜色对应的灰度值
        bMap[i] = (BYTE)(0.299 * lpbmi->bmiColors[i].rgbRed +

                         0.587 * lpbmi->bmiColors[i].rgbGreen +

                         0.114 * lpbmi->bmiColors[i].rgbBlue + 0.5);           
        // 更新DIB调色板红色分量
        lpbmi->bmiColors[i].rgbRed = i;   
       
        // 更新DIB调色板绿色分量
        lpbmi->bmiColors[i].rgbGreen = i;   
       
        // 更新DIB调色板蓝色分量
        lpbmi->bmiColors[i].rgbBlue = i;
           
        // 更新DIB调色板保留位
        lpbmi->bmiColors[i].rgbReserved = 0;

    }
    // 找到DIB图像象素起始位置
    lpDIBBits = ::FindDIBBits(lpDIB);
       
    // 获取图像宽度
    lWidth = ::DIBWidth(lpDIB);   

    // 获取图像高度
    lHeight = ::DIBHeight(lpDIB);   

    // 计算图像每行的字节数
    lLineBytes = WIDTHBYTES(lWidth * 8);   

    // 更换每个象素的颜色索引(即按照灰度映射表换成灰度值)
    //逐行扫描
    for(i = 0; i < lHeight; i++)
    {
        //逐列扫描
        for(j = 0; j < lWidth; j++)
        {
            // 指向DIB第i行,第j个象素的指针
            lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;                   
            // 变换
            *lpSrc = bMap[*lpSrc];
        }
    }

    //解除锁定
    ::GlobalUnlock ((HGLOBAL)hDIB);
}

 

 

// 相关工程文件

看我的资源

http://cay22.download.csdn.net/

你可能感兴趣的:(图像,byte,图像处理,float,c)