登山者的仰望

不仅要走好脚下的每一步,也要仰望山顶
c语言处理BMP--锐化,柔化,浮雕,灰度图(一)
#include"stdio.h"
//#include"alloc.h"
#include"dos.h"
//#include"graphics.h"
#include"math.h"

typedef   
struct
{
    
int     bfType;/*   类型标志,总是BM*/
    
long   bfSize;/*   文件大小*/
    
int   bfReserved1;
    
int   bfReserved2;
    
long   bfOffBits;/*   位图点阵偏移量*/
}
HEAD;
typedef     
struct
{
    
long   biSize;/*   结构体字节总数*/
    
long   biWidth;/*   图像宽度*/
    
long   biHeight;/*图像高度*/
    
int   biPlanes;/*   必须为1*/
    
int   biBitCount;/*   每个像素所占二进制位数,可能是1,4,8或   24*/
    
long   biCompress;/*压缩方式*/
    
long   biSizeImage;/*像素点阵大小*/
    
long   biXPelsPerMeter;/*   水平像素数*/
    
long   biYPelsPerMeter;/*   垂直像素数*/
    
long   biClrUsed;/*使用的颜色数*/
    
long   biClrImportant;/*重要颜色数*/
}
INFO;
typedef   
struct
{
    unsigned   
char     rgbBlue;   /*蓝色所占比重*/
    unsigned   
char     rgbGreen;   /*绿色所占比重*/
    unsigned   
char     rgbRed;   /*红色所占比重*/
    unsigned   
char     rgbReserved;/*保留字节*/
}
RGBQUAD;

int   Match_f(int   nRed,int   nGreen,int   nBlue);   /*寻找与像素匹配的调色板的序号*/
Sharp_f(FILE   
*fpi,   FILE   *fpo);   /*   锐化处理*/
Emboss_f(FILE   
*fpi,   FILE   *fpo);   /*浮雕效果处理*/
Smooth_f(FILE   
*fpi,FILE   *fpo);   /*柔化效果处理*/
Initial_f(
int   nChoice);   /*初始化图像文件*/
int Threshold(FILE *fpi,FILE *fpo);/*二值化*/

RGBQUAD     straPla[
256];   /*256色调色板*/
HEAD     strHead;
INFO   strInfo;
unsigned   
int   nWidth=512,nDepth=512;   /*处理512×512位图*/
unsigned   
char   naImage[64][512];
unsigned 
char ThresholdArray[64][512];

int   Match_f(int   nRed,int   nGreen,int   nBlue)   /*寻找与像素匹配的调色板的序号*/
{
    
long   int   nMax,nLength;
    
int   nNum=0,nCounti;
    unsigned   
int   nImageRed,nImageGreen,   nImageBlue;
    nImageRed
=(unsigned   int)(straPla[0].rgbRed);
    nImageGreen
=(unsigned   int)(straPla[0].rgbGreen);
    nImageBlue
=(unsigned   int)(straPla[0].rgbBlue);
    nMax
=(nRed-nImageRed)*(nRed-nImageRed)+(nGreen-nImageGreen)*(nGreen-nImageGreen)+(nBlue-nImageBlue)*(nBlue-nImageBlue);
    
for (nCounti=1;nCounti<256;nCounti++)
    
{
        nImageRed
=(unsigned   int)(straPla[nCounti].rgbRed);
        nImageGreen
=(unsigned   int)(straPla[nCounti].rgbGreen);
        nImageBlue
=(unsigned   int)(straPla[nCounti].rgbBlue);
        nLength
=(nRed-nImageRed)*(nRed-nImageRed)+(nGreen-nImageGreen)*(nGreen-nImageGreen)+(nBlue-nImageBlue)*(nBlue-nImageBlue);
        
if (nMax>nLength)
        
{
            nMax
=nLength;
            nNum
=nCounti;
            
if (nMax==0)
                
break;
        }

    }

    
return   nNum;
}

Emboss_f(FILE   
*fpi,   FILE   *fpo)   /*浮雕效果处理*/
{
    
int   nCounti,nCountj,nCountk,nCountl;
    
int   nRed,nBlue,nGreen;
    
int   nDx=1,nDy=1;
    unsigned   
int   nPixel1,nPixel2,nPixel;
    fread((
char   *)&strHead,1,sizeof(strHead),fpi);
    fread((
char   *)&strInfo,1,sizeof(strInfo),fpi);
    
for (nCounti=0;nCounti<256;nCounti++)
        fread((
char   *)&straPla[nCounti],1,sizeof(RGBQUAD),fpi);
    fwrite((
char   *)&strHead,1,sizeof(strHead),fpo);
    fwrite((
char*)&strInfo,1,sizeof(strInfo),fpo);
    
for (nCounti=0;nCounti<256;nCounti++)
        fwrite((
char   *)&straPla[nCounti],1,sizeof(RGBQUAD),fpo);
    
for (nCounti=0;nCounti<8;nCounti++)
    
{
        
for (nCountj=0;nCountj<64;nCountj++)
            fread(
&naImage[nCountj][0],1,nWidth,fpi);
        
for (nCountk=0;nCountk<64-1;nCountk++)
        
{
            
for (nCountl=0;nCountl<nWidth-1;nCountl++)
            
{
                nPixel1
=(unsigned   char)(naImage[nCountk][nCountl]);
                nPixel2
=(unsigned   char)(naImage[nCountk+nDx][nCountl+nDy]);
                nRed
=fabs(straPla[nPixel1].rgbRed-straPla[nPixel2].rgbRed+128);
                nGreen
=fabs(straPla[nPixel1].rgbGreen-straPla[nPixel2].rgbGreen+128);
                nBlue
=fabs(straPla[nPixel1].rgbBlue-straPla[nPixel2].rgbBlue+128);
                nPixel
=Match_f(nRed,nGreen,nBlue);
                naImage[nCountk][nCountl]
=nPixel;
            }

        }

        
for (nCountl=0;nCountl<nWidth-1;nCountl++)
        
{
            nPixel1
=(unsigned   char)(naImage[63][nCountl]);
            nPixel2
=(unsigned   char)(naImage[63][nCountl+nDy]);
            nRed
=fabs(straPla[nPixel1].rgbRed-straPla[nPixel2].rgbRed+128);
            nGreen
=fabs(straPla[nPixel1].rgbGreen-straPla[nPixel2].rgbGreen+128);
            nBlue
=fabs(straPla[nPixel1].rgbBlue-straPla[nPixel2].rgbBlue+128);
            nPixel
=Match_f(nRed,nGreen,nBlue);
            naImage[
63][nCountl]=nPixel;
        }

        
for (nCountj=0;nCountj<64;nCountj++)
            fwrite(
&naImage[nCountj][0],1,nWidth,fpo);
    }

}

Sharp_f(FILE   
*fpi,   FILE   *fpo)   /*   锐化处理*/
{
    
int   nCounti,nCountj,nCountk,nCountl;
    
int   nRed,nBlue,nGreen;
    
int   nDx=1,nDy=1;
    unsigned   
int   nPixel1,nPixel2,nPixel;
    fread((
char   *)&strHead,1,sizeof(strHead),fpi);
    fread((
char   *)&strInfo,1,sizeof(strInfo),fpi);
    
for (nCounti=0;nCounti<256;nCounti++)
        fread((
char   *)&straPla[nCounti],1,sizeof(RGBQUAD),fpi);
    fwrite((
char   *)&strHead,1,sizeof(strHead),fpo);
    fwrite((
char*)&strInfo,1,sizeof(strInfo),fpo);
    
for (nCounti=0;nCounti<256;nCounti++)
        fwrite((
char   *)&straPla[nCounti],1,sizeof(RGBQUAD),fpo);
    
for (nCounti=0;nCounti<8;nCounti++)
    
{
        
for (nCountj=0;nCountj<64;nCountj++)
            fread(
&naImage[nCountj][0],1,nWidth,fpi);
        
for (nCountk=1;nCountk<64-2;nCountk++)
            
for (nCountl=1;nCountl<nWidth-2;nCountl++)
            
{
                nPixel1
=(unsigned   char)(naImage[nCountk][nCountl]);
                nPixel2
=(unsigned   char)(naImage[nCountk-nDx][nCountl-nDy]);
                nRed
=straPla[nPixel1].rgbRed+0.5*(straPla[nPixel1].rgbRed-straPla[nPixel2].rgbRed);
                
/*0.5为锐化系数*/
                nGreen
=straPla[nPixel1].rgbGreen+0.5*(straPla[nPixel1].rgbGreen-straPla[nPixel2].rgbGreen);
                nBlue
=straPla[nPixel1].rgbBlue+0.5*(straPla[nPixel1].rgbBlue-straPla[nPixel2].rgbBlue);
                
if (nRed>255)
                    nRed
=255;
                
if (nRed<0)
                    nRed
=0;
                
if (nGreen>255)
                    nGreen
=255;
                
if (nGreen<0)
                    nGreen
=0;
                
if (nBlue>255)
                    nBlue
=255;
                
if (nBlue<0)
                    nBlue
=0;
                nPixel
=Match_f(nRed,nGreen,nBlue);
                naImage[nCountk][nCountl]
=nPixel;
            }

        
for (nCountj=0;nCountj<64;nCountj++)
            fwrite(
&naImage[nCountj][0],1,nWidth,fpo);
    }


}


Smooth_f(FILE   
*fpi,FILE   *fpo)   /*柔化效果处理*/
{
    
int   nCounti,nCountj,nCountk,nCountl,nCountm,nCountn,nRed,nGreen,nBlue;
    unsigned   nPixel;
    fread((
char   *)&strHead,1,sizeof(strHead),fpi);
    fread((
char   *)&strInfo,1,sizeof(strInfo),fpi);
    
for (nCounti=0;nCounti<256;nCounti++)
        fread((
char   *)&straPla[nCounti],1,sizeof(RGBQUAD),fpi);
    fwrite((
char   *)&strHead,1,sizeof(strHead),fpo);
    fwrite((
char*)&strInfo,1,sizeof(strInfo),fpo);
    
for (nCounti=0;nCounti<256;nCounti++)
        fwrite((
char   *)&straPla[nCounti],1,sizeof(RGBQUAD),fpo);
    
for (nCounti=0;nCounti<8;nCounti++)
    
{
        
for (nCountj=0;nCountj<64;nCountj++)
            fread(
&naImage[nCountj][0],1,nWidth,fpi);
        
for (nCountk=1;nCountk<64-2;nCountk++)
        
{
            
for (nCountl=1;nCountl<nWidth-2;nCountl++)
            
{
                nRed
=0,nGreen=0,nBlue=0;
                
for (nCountm=0;nCountm<3;nCountm++)  /*用9个点的均值柔化*/
                    
for (nCountn=0;nCountn<3;nCountn++)
                    
{
                        nPixel
=(unsigned   char)(naImage[nCountk-1+nCountm][nCountl-1+nCountn]);
                        nRed
+=straPla[nPixel].rgbRed;
                        nGreen
+=straPla[nPixel].rgbGreen;
                        nBlue
+=straPla[nPixel].rgbBlue;
                    }

                nRed
=nRed/9;
                nGreen
=nGreen/9;
                nBlue
=nBlue/9;
                nPixel
=Match_f(nRed,nGreen,nBlue);
                naImage[nCountk][nCountl]
=nPixel;
            }

        }

        
for (nCountj=0;nCountj<64;nCountj++)
            fwrite(
&naImage[nCountj][0],1,nWidth,fpo);
    }

}

int Threshold(FILE *fpi,FILE *fpo)
{
    
int   nCounti,nCountj,nCountk,nCountl;
    
int   nRed,nBlue,nGreen;
    
int   nDx=1,nDy=1;
    unsigned   
int   nPixel1,nPixel2,nPixel;
    
int ThresholdValue=1/*阈值*/
    
int  ihist[256]={0};/*图像直方图,256个点*/
    
int n, n1, n2, gmin, gmax;
    
double m1, m2, sum, csum, fmax, sb;
    
int i,j,k;
    
int cn;
    fread((
char   *)&strHead,1,sizeof(strHead),fpi);
    fread((
char   *)&strInfo,1,sizeof(strInfo),fpi);
    
for (nCounti=0;nCounti<256;nCounti++)
        fread((
char   *)&straPla[nCounti],1,sizeof(RGBQUAD),fpi);
    fwrite((
char   *)&strHead,1,sizeof(strHead),fpo);
    fwrite((
char*)&strInfo,1,sizeof(strInfo),fpo);
    
for (nCounti=0;nCounti<256;nCounti++)
        fwrite((
char   *)&straPla[nCounti],1,sizeof(RGBQUAD),fpo);

    
for (i=0;i<256;i++)// 对直方图置零
    {
        ihist[i]
=0;
    }

    gmin
=255;
    gmax
=0;
    
// 生成直方图
    for (nCounti=0;nCounti<8;nCounti++)
    
{
        
for (nCountj=0;nCountj<64;nCountj++)
            fread(
&naImage[nCountj][0],1,nWidth,fpi);
        
for (nCountk=0;nCountk<64;nCountk++)
            
for (nCountl=0;nCountl<nWidth;nCountl++)
            
{
                nPixel
=(unsigned   char)(naImage[nCountk][nCountl]);
                nRed
=straPla[nPixel].rgbRed;
                nGreen
=straPla[nPixel].rgbGreen;
                nBlue
=straPla[nPixel].rgbBlue;
                cn 
= ((nGreen*59+nRed*30+nBlue*11)/100);
                ihist[cn]
++;
                
if (cn > gmax) gmax=cn;
                
if (cn < gmin) gmin=cn;
            }

        
// set up everything
        sum = csum = 0.0;
        n 
= 0;
        
for (k = 0; k <= 255; k++)
        
{
            sum 
+= (double) k * (double) ihist[k]; /* x*f(x) 质量矩*/
            n 
+= ihist[k]; /* f(x) 质量 */
        }

        
if (n==0)
        
{
            
// if n has no value, there is problems
            return (60);
        }

        
// do the otsu global thresholding method
        fmax = -1.0;
        n1 
= 0;
        
for (k = 0; k < 255; k++)
        
{
            n1 
+= ihist[k];
            
if (n1==0)
            
{
                
continue;
            }

            n2 
= n - n1;
            
if (n2 == 0)
            
{
                
break;
            }

            csum 
+= (double) k *ihist[k];
            m1 
= csum / n1;
            m2 
= (sum - csum) / n2;
            sb 
= (double) n1 *(double) n2 *(m1 - m2) * (m1 - m2);
            
/* bbg: note: can be optimized. */
            
if (sb > fmax)
            
{
                fmax 
= sb;
                ThresholdValue 
= k;
            }

        }

        nPixel1
=Match_f(0,0,0);
        nPixel2
=Match_f(255,255,255);
        
for (nCountk=0;nCountk<64;nCountk++)
            
for (nCountl=0;nCountl<nWidth;nCountl++)
            
{
                nPixel
=(unsigned   char)(naImage[nCountk][nCountl]);
                nRed
=straPla[nPixel].rgbRed;
                nGreen
=straPla[nPixel].rgbGreen;
                nBlue
=straPla[nPixel].rgbBlue;
                cn 
= ((nGreen*59+nRed*30+nBlue*11)/100);
                
if (cn<=ThresholdValue)
                
{
                    naImage[nCountk][nCountl]
=nPixel1;
                    ThresholdArray[nCountk][nCountl]
=0;
                }

                
else
                
{
                    naImage[nCountk][nCountl]
=nPixel2;
                    ThresholdArray[nCountk][nCountl]
=0;
                }

            }

        
for (nCountj=0;nCountj<64;nCountj++)
            fwrite(
&naImage[nCountj][0],1,nWidth,fpo);
        
// at this point we have our thresholding value
        
//return ThresholdValue;
    }


}

Initial_f(
int   nChoice)
{
    
char   szFilena1[30],szFilena2[30];
    FILE   
*fpi,   *fpo;
    printf(
"Input   the   bmp   source   file:   ");
    scanf(
"%s",szFilena1);
    printf(
"Input   the   bmp   termini   file:   ");
    scanf(
"%s",   szFilena2);
    
if ((fpi=fopen(szFilena1,"rb"))==NULL)
    
{
        printf(
"OPEN   SOURCE   FILE   ERROR\n");
        exit(
0);
    }

    
if ((fpo=fopen(szFilena2,"wb"))==NULL)
    
{
        printf(
"OPEN   TERMINI   FILE   ERROR\n");
        exit(
0);
    }

    
if (nChoice==3)
        Emboss_f(fpi,fpo);
    
else
        
if (nChoice==2)
            Sharp_f(fpi,fpo);
        
else
            
if (nChoice==4)
                Threshold(fpi,fpo);
            
else   if (nChoice==1)
                Smooth_f(fpi,fpo);

    fclose(fpi);
    fclose(fpo);
}


void   main()
{
    
int   nChoice;
    
do
    
{
        printf(
"\n\t1.   Smooth\n");
        printf(
"\n\t2.   Sharp\n");
        printf(
"\n\t3.   Emboss\n");
        printf(
"\n\t4.   Threshold\n");
        printf(
"\n\t5.   Exit\n");
        scanf(
"%d",&nChoice);
        
switch (nChoice)
        
{
        
case   1:
        
case   2:
        
case   3:
        
case   4:
            Initial_f(nChoice);
            
break;
        
case   5:
            
break;
        
default:
            printf(
"Input   again!\n");
            
break;
        }

    }

    
while (nChoice!=5);
}

posted on 2008-06-08 00:12  光光GG  阅读(4097)  评论(4)    收藏  举报