灰度变换

灰度线性变换公式: D0=EH(D1) = aD1+b (变换后的像素点等于原像素点经一次线性变换得到)
包括:反色,折线变换 ,窗口变换
非线性变换 公式:D0=EH(D1)=Clog(1+|D1|)
包括:log 动态压缩变换,
将24位位图转换成灰度图:

/************************************************************************/
//      函数名称: GetGray()
//      参数: MyBitmap myBmp --------待处理的24位bmp位图
//      unsigned char* srcchar --------存放灰度图像的数组
//      返回值 无
//      说明 : 该函数用来得到24位位图的灰度图像
/************************************************************************/
void MyProcess::GetGray(MyBitmap myBmp,unsignedchar*srcchar
{
    if(myBmp.GetBitCount()!=24)return;
    int i,j;
    for(i=0;i<myBmp.GetHeight();i++)
    for(j=0;j<myBmp.GetWidth();j+=3)
    {
        unsignedchar b=myBmp.GetBmp()[i*myBmp.GetWidth()+j];
        unsignedchar g=myBmp.GetBmp()[i*myBmp.GetWidth()+j+1];
        unsignedchar r=myBmp.GetBmp()[i*myBmp.GetWidth()+j+2];
        unsignedchar h=(r*30+g*59+b*11)/100;
        srcchar[i*myBmp.GetBmpWidth()+j/3]= h;
    }
}

灰度直方图:

/************************************************************************
        函数名称: GetGrayIntensity()
        参数: unsigned char *gray --------待处理的灰度图
        int *grayInt --------存放灰度直方图的数组
        LONG width,LONG height-------图像的宽度和高度
        返回值 无
        说明 : 该函数用来得到灰度图像的直方图
************************************************************************/
void GetGrayIntensity(unsignedchar*gray,int*grayInt,LONG width,LONG height);//得到灰度图的灰度直方图
voidMyProcess::GetGrayIntensity(unsignedchar*gray,int*grayInt,LONG width,LONG height)
{
    int i,j;
    for(i=0;i<height;i++)
    for(j=0;j<width;j++)
    {
        int temp = gray[i*width+j];
        grayInt[temp]++;
    }
}

反色:

/************************************************************************
        函数名称: PointInvert()
        参数: unsigned char *bmp --------待处理的图像
        int x, int y ----------显示的位置
        LONG width,LONG height-------图像的宽度和高度
        返回值 无
        说明 : 该函数将图像进行反色变换处理,注意:会改变原图片
************************************************************************/
void PointInvert(unsignedchar*bmp,LONG width,LONG height);
void MyProcess::PointInvert(unsignedchar*bmp,LONG width,LONG height)
{
for(int i=0;i<height;i++)
for(int j=0;j<width;j++)
{
            bmp[i*width+j]=255-bmp[i*width+j];
}
}

灰度折线变换:

/************************************************************************
        函数名称: GrayStretch()
        参数: unsigned char *bmp --------待处理的图像
        LONG width,LONG height-------图像的宽度和高度
        BYTE bx1 -------折线1的原始灰度
        BYTE by1
        返回值 无
        说明 : 该函数将图像进行灰度折线变换
************************************************************************/
void GrayStretch(unsignedchar*bmp,LONG width,LONG height,BYTE bx1,BYTE by1,BYTE bx2,BYTE by2);
void MyProcess::GrayStretch(unsignedchar*bmp,LONG width,LONG height,BYTE bx1,BYTE by1,BYTE bx2,BYTE by2)
{
    LONG i,j;//循环变量
    BYTE bMap[256];
    for(i=0;i<=bx1;i++)
    {
        //判断bx1是否大于0(防止分母为0)
        if(bx1>0)
        {
            //线性变换
            bMap[i]=(BYTE) by1*i/bx1;
        }else
        {
            bMap[i]=0;
        }
    }
    for(;i<=bx2;i++)
    {
        //判断bx2是否大于0(防止分母为0)
        if(bx2!=bx1)
        {
            //线性变换
            bMap[i]=(BYTE)(by2-by1)*(i-bx1)/(bx2-bx1);
        }else
        {
            bMap[i]=by1;
        }
    }
    for(;i<256;i++)
    {
        if(bx2!=255)
        {
            bMap[i]=by2+(BYTE)((255-by2)*(i-bx2)/(255-bx2));
        }else
        {
            bMap[i]=255;
        }
    }
    for(i=0;i<height;i++)
    for(j=0;j<width;j++)
    {
        BYTE temp = bmp[i*width+j];
        bmp[i*width+j]= bMap[temp];
    }
}

灰度窗口变换:

/************************************************************************
        函数名称: GrayStretch()
        参数: unsigned char *bmp --------待处理的图像
        LONG width,LONG height-------图像的宽度和高度
        BYTE bLow    -------- 窗口下限
        BYTE bUp     -------- 窗口上限
        返回值 无
        说明 : 对图像进行灰度窗口变换,即小于下限为0,大于上限为255,中间线性变换
************************************************************************/
voidWindowTrans(BYTE *bmp,LONG width,LONG height ,BYTE bLow,BYTE bUp);
voidMyProcess::WindowTrans(BYTE *bmp,LONG width,LONG height ,BYTE bLow,BYTE bUp)
{
    LONG i,j;//循环变量
    for(i=0;i<height;i++)
    for(j=0;j<width;j++)
    {
        BYTE temp = bmp[i*width+j];
        if(temp < bLow) bmp[i*width+j]=0;
        else if(temp > bUp) bmp[i*width+j]=255;
    }
}

灰度非线性变换:

/************************************************************************
        函数名称: DynamicCompress()
        参数: unsigned char *bmp --------待处理的图像
        LONG width,LONG height-------图像的宽度和高度
        int C --------- 非线性变换比例常数
        返回值 无
        说明 : 对图像进行非线性变换 公式:D0=EH(D1)=Clog(1+|D1|),用于动态范围过大时
************************************************************************/
void DynamicCompress(BYTE *bmp,LONG width,LONG height,int C);
void MyProcess::DynamicCompress(BYTE *bmp,LONG width,LONG height,int C)
{
    LONG i,j;//循环变量
    for(i=0;i<height;i++)
    for(j=0;j<width;j++)
    {
            bmp[i*width+j]= C*log(1+bmp[i*width+j]);
    }
}

均衡变换:

/************************************************************************
        函数名称: PointEqua()
        参数: BYTE *bmp --------待处理的图像
        LONG width,LONG height-------图像的宽度和高度
        int type --------图像类型,0:24位彩色,1:灰度
        返回值 无
        说明 : 对图像进行均衡变换
************************************************************************/
void PointEqua(BYTE *bmp,LONG width,LONG height,int type=0);
void MyProcess::PointEqua(BYTE *bmp,LONG width,LONG height,int type)
{
    LONG i,j;
    int R[256],G[256],B[256];
    memset(R,0,sizeof(R));
    memset(G,0,sizeof(G));
    memset(B,0,sizeof(B));
    //统计各个变量的个数
    if(type==0)GetIntensity(bmp,width,height,R,G,B);
    else if(type==1)GetGrayIntensity(bmp,R,width,height);
    float temp_r[256],temp_g[256],temp_b[256];
    memset(temp_r,0,sizeof(temp_r));
    memset(temp_g,0,sizeof(temp_g));
    memset(temp_b,0,sizeof(temp_b));
    double sum ;
    if(type==0) sum = width*height/3;
    else if(type==1) sum=width*height;
    //获得各个变量的百分比
    for(i=0;i<256;i++)
    {
        if(i==0)
        {
            if(type==0)
            {
                temp_r[0]=(double)R[0]/sum;
                temp_g[0]=(double)G[0]/sum;
                temp_b[0]=(double)B[0]/sum;
            }else if(type==1)
            {
                temp_r[0]=(double)R[0]/sum;
            }
        }
        else
        {
            if(type==0)
            {
                    temp_r[i]=temp_r[i-1]+(double)R[i]/sum;
                    temp_g[i]=temp_g[i-1]+(double)G[i]/sum;
                    temp_b[i]=temp_b[i-1]+(double)B[i]/sum;
            }elseif(type==1)
            {
                    temp_r[i]=temp_r[i-1]+(double)R[i]/sum;
            }
        }
    }
    //计算均衡值
    for(i=0;i<256;i++)
    {
        if(type==0)
        {
            temp_r[i]=(int)(255.0f*temp_r[i]+0.5);
            temp_g[i]=(int)(255.0f*temp_g[i]+0.5);
            temp_b[i]=(int)(255.0f*temp_b[i]+0.5);
        }else if(type==1)
        {
            temp_r[i]=(int)(255.0f*temp_r[i]+0.5);
        }
    }
    for(i=0;i<height;i++)
    for(j=0;j<width;j++)
    {
        if(type==0)
        {
            bmp[i*width+j]=temp_r[bmp[i*width+j]];
            j++;
            bmp[i*width+j]=temp_g[bmp[i*width+j]];
            j++;
            bmp[i*width+j]=temp_b[bmp[i*width+j]];
        }else if(type==1)
        {
            bmp[i*width+j]=temp_r[bmp[i*width+j]];
        }
    }
}

灰度匹配变换

/************************************************************************
        函数名称: PointEqua()
        参数: BYTE *bmp --------待处理的图像
        LONG width,LONG height-------图像的宽度和高度
        BYTE bNum ----规定直方图灰度级数
        int *Nu-------规定直方图灰度映射关系
        float *Pu-----规定直方图各灰度的分布概率
        int type --------图像类型,0:24位彩色,1:灰度
        返回值 无
        说明 : 对图像进行单映射规则直方图规定化变换
************************************************************************/
void PointSML(BYTE *bmp,LONG width,LONG height,BYTE bNum,int*Nu,float*Pu,int type=0);
void MyProcess::PointSML(BYTE *bmp,LONG width,LONG height,BYTE bNum,int*Nu,float*Pu,int type)
{
    LONG i,j;
    int R[256],G[256],B[256];
    int mMap_r[256],mMap_g[256],mMap_b[256];
    memset(R,0,sizeof(R));
    memset(G,0,sizeof(G));
    memset(B,0,sizeof(B));
    if(type==0)GetIntensity(bmp,width,height,R,G,B);
    else if(type==1)GetGrayIntensity(bmp,R,width,height);
    float temp_r[256],temp_g[256],temp_b[256];
    double sum ;
    if(type==0) sum = width*height/3;
    elseif(type==1) sum=width*height;
    //计算原始累计直方图
    for(i=0;i<256;i++)
    {
        if(i==0)
        {
            if(type==0)
            {
                temp_r[0]=(double)R[0]/sum;
                temp_g[0]=(double)G[0]/sum;
                temp_b[0]=(double)B[0]/sum;
            }elseif(type==1)
            {
                temp_r[0]=(double)R[0]/sum;
            }
        }
        else
        {
            if(type==0)
            {
                temp_r[i]=temp_r[i-1]+(double)R[i]/sum;
                temp_g[i]=temp_g[i-1]+(double)G[i]/sum;
                temp_b[i]=temp_b[i-1]+(double)B[i]/sum;
            }else if(type==1)
            {
                temp_r[i]=temp_r[i-1]+(double)R[i]/sum;
            }
        }
    }
    //计算规定累计直方图
    for(i=1;i<bNum;i++)
    {
        Pu[i]=Pu[i-1]+Pu[i];
    }
    //确定映射对应关系
    for(i=0;i<256;i++)
    {
        //最接近的规定直方图灰度级
        int m_r=0,m_g=0,m_b=0;
        //最小差值
        float f_r=1,f_g=1,f_b=1;
        //寻找最小差值
        for(j=0;j<bNum;j++)
        {
            float f_now=abs(temp_r[i]-Pu[j]);
            if(f_now < f_r)
            {
                f_r=f_now;
                mMap_r[i]=j;
            }
            if(type==0)
            {
                float f_now_g=abs(temp_g[i]-Pu[j]);
                if(f_now < f_g)
                {
                    f_g=f_now;
                    mMap_g[i]=j;
                }
                float f_now_b=abs(temp_b[i]-Pu[j]);
                if(f_now < f_b)
                {
                    f_b=f_now;
                    mMap_b[i]=j;
                }
            }
        }
    }
    for(i=0;i<height;i++)
    for(j=0;j<width;j++)
    {
        if(type==0)
        {
            bmp[i*width+j]=mMap_r[bmp[i*width+j]];
            j++;
            bmp[i*width+j]=mMap_g[bmp[i*width+j]];
            j++;
            bmp[i*width+j]=mMap_b[bmp[i*width+j]];
        }else if(type==1)
        {
            bmp[i*width+j]=mMap_r[bmp[i*width+j]];
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值