一、实验目的: 掌握在计算机上显示图象的方法
二、实验要求:
1、熟悉参考程序,熟悉C语言。
2、输入图象显示源程序,建立C语言程序调试环境。
3、在计算机屏幕上显示制定的图像(提供两个图像文件A2和B2),并计算显示其灰度直方图。
4、修改程序,在屏幕上显示256*256的对度图像(灰度变化分别是左边暗-右边亮、左下暗-中间亮-右上暗、左上暗-中间亮-右下暗)。
三、实验程序
#include #include #include #include #include #include #include #include #include #include #include #include union REGS iregs, oregs, sregs; double data1[512], data2[512], max1, bu1[3], bu2[3]; unsigned char image1[128][128], image2[128][128]; int max; main(int argc, char *argv[]) /----参数argc代表了输入参数的个数,char *argv[]表示传入的参数的字符串,是一个字符串数组。------/ { FILE *fp, *fp1; int a,b,c,x,y,z; int n, isi, driver, mode1; unsigned char d[128][128], datam[256]; driver=DETECT; mode1=2; initgraph(&driver,&mode1,"") ;/---initgraph()函数直接进行的图形初始化程序------/ iregs.x.ax=0x0100; iregs.x.cx=0x0000; int86(0x10,&iregs,&oregs); closegraph(); driver=DETECT; mode1=2; initgraph(&driver,&mode1,""); iregs.x.ax=0x005f; int86(0x10,&iregs,&oregs); for(a=0;a<256;a++){ iregs.x.ax=0x1010; iregs.x.bx=a; iregs.h.dh=a/4; iregs.h.ch=a/4; iregs.h.cl=a/4; int86(0x10,&iregs,&oregs); } fp=fopen("f:\\\\exp\\\c\\\\a2 for(a=0;a<;a++){ fread(datam,,1,fp); for(b=0;b<;b++) { putpixel2(b*2+256,a*2+100,(int)datam[b]); putpixel2(b*2+257,a*2+100,(int)datam[b]); putpixel2(b*2+256,a*2+101,(int)datam[b]); putpixel2(b*2+257,a*2+101,(int)datam[b]); } } fclose(fp); getch(); closegraph(); } getpixel2( int a, int b ) /--显示像素---/ { iregs.h.ah=0xd; iregs.x.dx=b; iregs.x.cx=a; iregs.x.bx=0; int86(0x10,&iregs,&oregs); return(oregs.h.al); } putpixel2( int a, int b,int num) { iregs.h.ah=0xc; iregs.h.al=num; iregs.x.dx=b; iregs.x.cx=a; iregs.x.bx=0; int86(0x10,&iregs,&oregs); } Ⅰ、显示256*256的灰度图象(灰度变化分别是左边暗-右边亮)的程序修改: 红色区域内改为 fp=fopen(argv[1],"rb"); for(a=0;a<;a++){ fread(datam,,1,fp); for(b=0;b<;b++) { putpixel2(b*2+256,a*2+100, b); putpixel2(b*2+257,a*2+100,b); putpixel2(b*2+256,a*2+101, b); putpixel2(b*2+257,a*2+101,b); Ⅱ、显示256*256的灰度图象(灰度变化分别是左下暗-中间亮-右上暗)的程序修改: 红色区域内改为 fp=fopen(argv[1],"rb"); for(a=0;a<256;a++){ fread(datam,256,1,fp); for(b=0;b<256;b++) { putpixel2(b*2+256,a*2+100,256-abs(a+b-256)); putpixel2(b*2+257,a*2+100, 256-abs(a+b-256)); putpixel2(b*2+256,a*2+101, 256-abs(a+b-256)); putpixel2(b*2+257,a*2+101, 256-abs(a+b-256)); Ⅲ、显示256*256的灰度图象(灰度变化分别是左上暗-中间亮-右下暗)的程序修改: 红色区域内改为 fp=fopen(argv[1],"rb"); for(a=0;a<256;a++){ fread(datam,256,1,fp); for(b=0;b<256;b++) { putpixel2(b*2+256,a*2+100, abs(a+b-256)); putpixel2(b*2+257,a*2+100,abs(a+b-256)); putpixel2(b*2+256,a*2+101, abs(a+b-256)); putpixel2(b*2+257,a*2+101, abs(a+b-256)); 四、实验小结: 通过本次实验学会了如何用c语言显示图像以及用c语言进行图像的位置显示和位置灰度变换的处理的方法。 实验二 图象的二维傅立叶变换 一、实验目的:掌握在计算机上进行二维傅立叶变换的编程方法以及显示变换图象的方法 二、实验要求: 1、编写二维傅立叶变换的C语言程序及相应的显示程序。 2、建立输入图象,在*的白色图象矩阵的中心建立16*16的黑色矩形图像点阵,形成图象文件(共4096字节)。 3、对输入图象进行变换,将原始图象及变换图象都显示于屏幕上。 4、调整输入图象中白色矩形的尺寸,再进行变换,比较变换结果。 5、建立输入图象,在*的白色图象矩阵的中心建立半径为6个像素黑色的圆,形成图象文件。对输入图象进行变换,将原始图象及变换图象都显示于屏幕上。调整圆半径的尺寸,比较变换结果。 三、实验程序: 正方形的傅里叶变换: for(a=0;a<128;a++){ for(b=0;b<128;b++) { if(a>=40&&a<88&&b>=40&&b<88) data1[b]=100.0; else data1[b]=0.0; data2[b]=0.0; putpixel2(b,a+200,255-(int)data1[b]); } 程序运行结果如下: 较大的正方形的傅里叶变换: for(a=0;a<128;a++){ for(b=0;b<128;b++) { if(a>=25&&a<120&&b>=25&&b<120) data1[b]=100.0; else data1[b]=0.0; data2[b]=0.0; putpixel2(b,a+200,255-(int)data1[b]); } 程序运行结果如下: 矩形的傅里叶变换 for(a=0;a<128;a++){ for(b=0;b<128;b++) { if(a>=58&&a<70&&b>=40&&b<88) data1[b]=100.0; else data1[b]=0.0; data2[b]=0.0; putpixel2(b+400,a+150,255-(int)data1[b]); } 程序运行结果如下: 矩形的傅里叶变换 for(a=0;a<128;a++){ for(b=0;b<128;b++) { if(a>=40&&a<88&&b>=58&&b<70) data1[b]=100.0; else data1[b]=0.0; data2[b]=0.0; putpixel2(b+400,a+150,255-(int)data1[b]); } 程序运行结果如下: 矩形的傅里叶变换 for(a=0;a<128;a++){ for(b=0;b<128;b++) { if(a+b>=100&&a+b<=166&&(a-b<=20)&&(b-a<=20) data1[b]=100.0; else data1[b]=0.0; data2[b]=0.0; putpixel2(b+400,a+150,255-(int)data1[b]); } 程序运行结果如下: 矩形的傅里叶变换 for(a=0;a<128;a++){ for(b=0;b<128;b++) { if(a+b>=120&&a+b<=146&&(a-b<=50)&&(b-a)<=50) data1[b]=100.0; else data1[b]=0.0; data2[b]=0.0; putpixel2(b+400,a+150,255-(int)data1[b]); } 程序运行结果如下: 圆的傅里叶变换 for(a=0;a<128;a++){ for(b=0;b<128;b++) { if((a-63)*(a-63)+(b-63)*(b-63)<=24*24) data1[b]=100.0; else data1[b]=0.0; data2[b]=0.0; putpixel2(b+400,a+150,255-(int)data1[b]); } 程序运行结果如下: 四、实验小结: 通过本次实验,掌握了二维图像傅立叶变换的编程方法以及显示变换图像的方法。 实验三 图象的增强 一、实验目的:掌握在计算机上进行直方图均衡化及四点平滑的方法 二、实验要求: 1、编写直方图均衡化、四点平滑的C语言程序及相应的显示程序。 2、对指定图象进行直方图均衡化,将原始图象及增强后的图象都显示于屏幕上,比较增强的效果。 3、对指定图象进行四点平滑,将原始图象及增强后的图象都显示于屏幕上,比较增强的效果。 4、对指定图象用3×3模板进行平滑,将原始图象及增强后的图象都显示于屏幕上,比较增强的效果。 5、对指定图象用不同的3×3加权模板进行平滑,将原始图象及增强后的图象都显示于屏幕上,比较增强的效果。 三、实验程序: (1)直方图均衡化 enchence() { int a,b,c,d,x,y; long data1[256]; for (c=0;c<256;c++)data1[c]=0; for(b=0;b<;b++) for(a=0;a<;a++) data1[*(buf+b*+a)]++; for(c=0;c<255;c++) data1[c+1]=data1[c]+data1[c+1]; for(c=0;c<256;c++) data1[c]=data1[c]*(long)255/(long)4096; for(b=0;b<;b++) for(a=0;a<;a++) *(buf+b*+a)=data1[*(buf+b*+a)]; for(y=0;y<;y++) for(x=0;x<;x++){ putpixel2(x*2+300,y*2+120,*(buf+(long)y*+x)); putpixel2(x*2+301,y*2+120,*(buf+(long)y*+x)); putpixel2(x*2+300,y*2+121,*(buf+(long)y*+x)); putpixel2(x*2+301,y*2+121,*(buf+(long)y*+x)); } } 图像显示如下: (2)四点平滑 enchence() { int a,b,c,d,x,y; unsigned char datam[]; int ss[][]; int mm[][]; FILE *fp; fp=fopen("e:\\\\dip\\\c\\\\a2 for(a=0;a<;a++) { fread(datam,,1,fp); for(b=0;b<;b++) {ss[a][b]=(int)datam[b];} } for(y=1;y<63;y++) for(x=1;x<63;x++){ mm[y][x]=(ss[y+1][x]+ss[y][x-1]+ss[y-1][x]+ss[y][x+1])/4; putpixel2(x*2+180,y*2+60,mm[y][x]); putpixel2(x*2+181,y*2+60,mm[y][x]); putpixel2(x*2+180,y*2+61,mm[y][x]); putpixel2(x*2+181,y*2+61,mm[y][x]); } } 图像显示如下: 3×3模板平滑,原始图象及增强后的图象 enchence() { int a,b,c,d,x,y; unsigned char datam[]; int ss[][]; int qq[][]; FILE *fp; fp=fopen("e:\\\\dip\\\c\\\\a2 for(a=0;a<;a++) { fread(datam,,1,fp); for(b=0;b<;b++) {ss[a][b]=(int)datam[b];} } for(y=1;y<63;y++) for(x=1;x<63;x++){ qq[y][x]=(ss[y][x]+ss[y+1][x]+ss[y][x-1]+ss[y-1][x]+ss[y][x+1]+ss[y+1][x-1]+ss[y-1][x-1]+ss[y-1][x+1]+ss[y+1][x+1])/9; putpixel2(x*2+180,y*2+60,qq[y][x]); putpixel2(x*2+181,y*2+60,qq[y][x]); putpixel2(x*2+180,y*2+61,qq[y][x]); putpixel2(x*2+181,y*2+61,qq[y][x]); } } 图像显示如下: 不同的3×3加权模板平滑 3×3Box模板的主程序如下 int a,b,c,d,x,y; for(b=1;b<63;b++) for(a=1;a<63;a++) {*(buf+b*+a)=(*(buf+(b-1)*+a-1)+*(buf+(b-1)*+a)+*(buf+(b+1)*+a+1)+*(buf+b*+a-1)+*(buf+b*+a)+*(buf+b*+a+1)+*(buf+(b+1)*+a-1)+*(buf+(b+1)*+a)+*(buf+(b+1)*+a+1))/9;} for(y=0;y<;y++) for(x=0;x<;x++){ putpixel2(x*2+300,y*2+120,*(buf+(long)y*+x)); putpixel2(x*2+301,y*2+120,*(buf+(long)y*+x)); putpixel2(x*2+300,y*2+121,*(buf+(long)y*+x)); putpixel2(x*2+301,y*2+121,*(buf+(long)y*+x)); 显示的图像如下 3×3高斯模板主程序如下: int a,b,c,d,x,y; for(b=1;b<63;b++) for(a=1;a<63;a++) {*(buf+b*+a)=(*(buf+(b-1)*+a-1)+(*(buf+(b-1)*+a))*2+*(buf+(b+1)*+a+1)+(*(buf+b*+a-1))*2+(*(buf+b*+a))*4+(*(buf+b*+a+1))*2+*(buf+(b+1)*+a-1)+(*(buf+(b+1)*+a))*2+*(buf+(b+1)*+a+1))/16;} for(y=0;y<;y++) for(x=0;x<;x++){ putpixel2(x*2+300,y*2+120,*(buf+(long)y*+x)); putpixel2(x*2+301,y*2+120,*(buf+(long)y*+x)); putpixel2(x*2+300,y*2+121,*(buf+(long)y*+x)); putpixel2(x*2+301,y*2+121,*(buf+(long)y*+x)); 显示的图像如下: 四、实验小结: 通过本次实验掌握在计算机上进行直方图均衡化,四点平滑,八点平滑,邻域平均法及中值滤波等进行图像平滑的方法。 实验四 图象的增强 一、实验目的: 掌握在计算机上进行图象平滑、图象锐化特别是中值滤波平滑及拉普拉斯算子锐化的方法 二、实验要求: 1.编写中值滤波的C语言程序以及相应的显示程序。 2.对指定图象进行中值滤波增强,将原始图象及增强后的图象都显示于屏幕上,比较增强的效果。可与实验三的四点平滑的结果进行比较。 3.编写简单锐化(简单梯度算法、ROBERT算子)及拉普拉斯算子锐化的C语言程序以及相应的显示程序。 4.对指定图象进行简单梯度锐化和拉普拉斯算子增强,将原始图象及增强后的图象都显示于屏幕上,比较增强的效果。 三、实验内容及程序: 中值滤波的C语言主程序如下: int a,b,c,d,x,y; unsigned char datam[]; int ss[][]; int mm[][],m[]; int qq[9]; int i,j; for(a=0;a<;a++) { fread(datam,,1,fp); for(b=0;b<;b++) {ss[a][b]=(int)datam[b];} } for(y=1;y<63;y++) for(x=1;x<63;x++){{qq[0]=ss[y-1][x-1];qq[1]=ss[y-1][x];qq[2]=ss[y-1][x+1]; qq[3]=ss[y][x-1];qq[4]=ss[y][x];qq[5]=ss[y][x+1]; qq[6]=ss[y+1][x-1];qq[7]=ss[y+1][x];qq[8]=ss[y+1][x+1]; } for(i=0;i<8;i++) {for(j=i+1;j<9;j++) if(qq[i]>qq[j]) {c=qq[i];qq[i]=qq[j];qq[j]=c;}} mm[y][x]=qq[4]; putpixel2(x*2+300,y*2+120,mm[y][x]); putpixel2(x*2+301,y*2+120,mm[y][x]); putpixel2(x*2+300,y*2+121,mm[y][x]); putpixel2(x*2+301,y*2+121,mm[y][x]); 显示后的图像如下所示: ROBERT算子的主程序: int a,b,c,d,x,y; unsigned char datam[]; int ss[][]; int mm[][]; for(a=0;a<;a++) { fread(datam,,1,fp); for(b=0;b<;b++) {ss[a][b]=(int)datam[b]; } } for(y=1;y<63;y++) for(x=1;x<63;x++){ mm[y][x]=(abs(ss[y+1][x]-ss[y][x])+abs(ss[y][x+1]-ss[y][x])+ss[y][x]); putpixel2(x*2+180,y*2+60,mm[y][x]); putpixel2(x*2+181,y*2+60,mm[y][x]); putpixel2(x*2+180,y*2+61,mm[y][x]); putpixel2(x*2+181,y*2+61,mm[y][x]); 显示后的图像如下: 水平垂直算法的主程序: int a,b,c,d,x,y; unsigned char datam[]; int ss[][]; int mm[][]; for(a=0;a<;a++) { fread(datam,,1,fp); for(b=0;b<;b++) {ss[a][b]=(int)datam[b]; } } for(y=1;y<63;y++) for(x=1;x<63;x++){ mm[y][x]=(abs(ss[y+1][x]-ss[y][x])+abs(ss[y][x+1]-ss[y][x])+ss[y][x]); putpixel2(x*2+180,y*2+60,mm[y][x]); putpixel2(x*2+181,y*2+60,mm[y][x]); putpixel2(x*2+180,y*2+61,mm[y][x]); putpixel2(x*2+181,y*2+61,mm[y][x]); 显示后的图像如下: 拉普拉斯算子锐化的C语言程序 int a,b,c,d,x,y; unsigned char datam[]; int ss[][]; int mm[][]; for(a=0;a<;a++) { fread(datam,,1,fp); for(b=0;b<;b++) {ss[a][b]=(int)datam[b]; } } for(y=1;y<63;y++) for(x=1;x<63;x++){ mm[y][x]=(-ss[y+1][x]+5*ss[y][x]-ss[y][x+1]-ss[y-1][x]-ss[y][x-1]); putpixel2(x*2+180,y*2+60,mm[y][x]); putpixel2(x*2+181,y*2+60,mm[y][x]); putpixel2(x*2+180,y*2+61,mm[y][x]); putpixel2(x*2+181,y*2+61,mm[y][x]); 显示后的图像如下: 实验小结: 通过本次实验,掌握了在计算机上进行图象锐化特别是拉普拉斯算子锐化的方法。了解了中值滤波原理:设置一个奇数点的滑动窗口,将窗口中心点的像素值用窗口内各点的中值代替。锐化目的:增强图像的边缘或轮廓。提高了数字图像处理的理论知识及在计算机上实现的方法。 实验五 图像二值化 一、实验目的: 掌握在计算机上进行灰度图象二值化处理,包括直方图法、微分直方图方法等; 二、实验要求: 1.编写图像二值化的C语言程序以及相应的显示程序。(直方图法和微分直方图法) 2.对指定图象进行直方图法二值化处理,将原始图象及二值化后的图象都显示于屏幕上,查看图像分割的效果。 3、对指定图象进行微分直方图法二值化处理,将原始图象及二值化后的图象都显示于屏幕上,查看图像分割的效果,并与2的结果进行比较。 三、实验内容: 参考程序: #include #include #include #include #include #include #include #include #include #include #include #include unsigned char huge *buf; union REGS iregs,oregs; struct SREGS sreg; main(argc,argv) /* l */ int argc; char *argv[]; {FILE *handle, *fp1, *fp2; int driver,mode1,i, a, b, c; unsigned char as[2]; driver=DETECT; mode1=2; initgraph(&driver,&mode1,""); iregs.x.ax=0x0100; iregs.x.cx=0x0000; int86(0x10,&iregs,&oregs); closegraph(); driver=DETECT; mode1=2; initgraph(&driver,&mode1,""); iregs.x.ax=0x0013; int86(0x10,&iregs,&oregs); for(a=0;a<256;a++){ iregs.x.ax=0x1010; iregs.x.bx=a; iregs.h.dh=a/4; iregs.h.ch=a/4; iregs.h.cl=a/4; int86(0x10,&iregs,&oregs); } buf =(char huge *)farmalloc( (unsigned long)0x10010 ); buf = MK_FP(FP_SEG(buf)+1,0); handle=fopen("E:\\\urbo\\\\TC201E\\\\A2 if(! handle){ cprintf("File open error !"); exit(-1); } imglod(handle); fclose(handle); enchence(); getch(); closegraph(); } imglod(handle) FILE *handle; { unsigned int b, x, y; int res,i,j; fread( ( char far * )buf, , , handle); for(y=0;y<;y++) for(x=0;x<;x++){ putpixel2(x*2+100,y*2+120,*(buf+(long)y*+x)); putpixel2(x*2+101,y*2+120,*(buf+(long)y*+x)); putpixel2(x*2+100,y*2+121,*(buf+(long)y*+x)); putpixel2(x*2+101,y*2+121,*(buf+(long)y*+x)); } } putpixel2( int a, int b,int num) {iregs.h.ah=0xc; iregs.h.al=num; iregs.x.dx=b; iregs.x.cx=a; iregs.x.bx=0; int86(0x10,&iregs,&oregs); } enchence() {int a,b,c,d,x,y; long data1[256]; for (c=0;c<256;c++)data1[c]=0; for(b=0;b<;b++) for(a=0;a<;a++) data1[*(buf+b*+a)]++; for(c=0;c<255;c++) data1[c+1]=data1[c]+data1[c+1]; for(c=0;c<256;c++) data1[c]=data1[c]*(long)255/(long)4096; for(b=0;b<;b++) for(a=0;a<;a++) *(buf+b*+a)=data1[*(buf+b*+a)]; for(y=0;y<;y++) for(x=0;x<;x++){ putpixel2(x*2+300,y*2+120,*(buf+(long)y*+x)); putpixel2(x*2+301,y*2+120,*(buf+(long)y*+x)); putpixel2(x*2+300,y*2+121,*(buf+(long)y*+x)); putpixel2(x*2+301,y*2+121,*(buf+(long)y*+x)); } } 四、直方图法二值化处理 核心程序: enchence() {int a,b,c,d,x,y; long data1[256]; long sum=0; long e; for (c=0;c<256;c++)data1[c]=0; for(b=0;b<;b++) for(a=0;a<;a++) data1[*(buf+b*+a)]++; for(c=0;c<255;c++) sum=data1[c]*c+sum; e=sum/4096; for(b=0;b<;b++) for(a=0;a<;a++) {if(*(buf+b*+a)>=e) *(buf+b*+a)=255; else *(buf+b*+a)=0;} for(y=0;y<;y++) for(x=0;x<;x++){ putpixel2(x*2+300,y*2+120,*(buf+(long)y*+x)); putpixel2(x*2+301,y*2+120,*(buf+(long)y*+x)); putpixel2(x*2+300,y*2+121,*(buf+(long)y*+x)); putpixel2(x*2+301,y*2+121,*(buf+(long)y*+x)); } 五、实验小结: 通过本次实验, 掌握了在计算机上进行灰度图象二值化处理,包括直方图法、微分直方图方法等。