#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);
}
![]()