灰度变换

来源:互联网 发布:我要学编程 编辑:程序博客网 时间:2024/05/16 10:24

灰度线性变换公式: 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 0
原创粉丝点击