首页 > 技术文章 > 图像处理 基于Visual C++编程 学习笔记 (3)显示灰度图像和二值化图像

kylehz 2015-05-09 18:43 原文

灰度图imggray

有了上面的基础,灰度图就相当简单了

彩色图转灰度方法:

1.浮点算法:Gray=R*0.3+G*0.59+B*0.11 
2.整数方法:Gray=(R*30+G*59+B*11)/100 
3.移位方法:Gray =(R*28+G*151+B*77)>>8;  ??
4.平均值法:Gray=(R+G+B)/3; 
5.仅取绿色:Gray=G; 

这里使用浮点算法

void imggray::showgray(CDC *pDC, CRect rc)
{
    ReadBitData();
    unsigned int i,j;
    for(i=0;i<vImageHeight();i++){
        for(j=0;j<vImageWidth();j++){
            unsigned char R = img[3*(i*vImageWidth() + j)];
            unsigned char G = img[3*(i*vImageWidth() + j) + 1];
            unsigned char B = img[3*(i*vImageWidth() + j) + 2];
            unsigned char GRAY=(unsigned char)(0.30*R+0.59*G+0.11*B);
            R=G=B=GRAY;
            pDC->SetPixel((rc.Width()-vImageWidth())/2+j,(rc.Height()-vImageHeight())/2+i,RGB(R,G,B));
        }
    }
}
void imggray::showgray2(CDC *pDC, CRect rc)//快速显示
{
     unsigned int _img_w = vImageWidth()*3;
    if(_img_w%4!=0)_img_w=(_img_w/4+1)*4;
    unsigned int i,j,x,y;
    y=vImageHeight();
    x=vImageWidth();
    for(i=0;i<y;i++){
        for(j=0;j<x;j++){
            unsigned char B=raw_img[i*_img_w+j*3];
            unsigned char G=raw_img[i*_img_w+j*3+1];
            unsigned char R=raw_img[i*_img_w+j*3+2];
            unsigned char GRAY=(unsigned char)(0.30*R+0.59*G+0.11*B);
            raw_img[i*_img_w+j*3]   = GRAY;
            raw_img[i*_img_w+j*3+1] = GRAY;
            raw_img[i*_img_w+j*3+2] = GRAY;    
        }
    }
    imshow2(pDC, rc);
}

灰度均衡:

按照灰度的分布情况,将灰度像素平均分布到0-255之间(建立灰度级表),让后分配根据这个表指定各个点的像素

void imggray::GrayEqualize(unsigned char *_img)
{
    unsigned char map[256];
    int i,cnt[256],scnt[256];
    for(i=0;i<256;i++){
        cnt[i]=0;
        scnt[i]=0;
    }
    for(i=0;i<data_size;i++)
    {
        cnt[_img[i]]++;
    }
    scnt[0]=cnt[0];
    for(i=1;i<256;i++)
    {
        scnt[i]=scnt[i-1]+cnt[i];
    }
    for(i=0;i<256;i++)
    {
        map[i]=scnt[i]*255*1.0/data_size;
    }
    for(i=0;i<data_size;i++)
    {
        _img[i]=map[_img[i]];
    }
}

效果图: 

二值化图像imgbinary

基于直方图均衡(平均值法)的二值化

void imgbinary::binary()//基于直方图
{
    int i,sum=0;
    for(i=0;i<data_size;i++)sum+=img_g[i];
    int avg=sum/data_size;
    for(i=0;i<data_size;i++)
    {
        if(img_g[i]>avg)img_b[i]=true;
        else img_b[i]=false;
    }
}

 

推荐阅读