实例介绍
【实例截图】
滤波之前
滤波之后
【核心代码】
#include <stdio.h> #include <stdlib.h> #include <math.h> #include "bmpstruct.h" /***************************************************************************************/ /*************读取BMP文件的文件头,并保存于filehead指向的区域***************************/ /***************************************************************************************/ int read_bmp_filehead( char* bmpName, BITMAPFILEHEADER* filehead) { FILE* fp; fp=fopen(bmpName, "rb"); if (fp==NULL) { printf("Can't open %s\n",bmpName); return 0; } else { fread(&filehead->bfType, 2, 1, fp);//从BMP文件读取2个字节的数据 fread(&filehead->bfSize, 4, 1, fp);//从BMP文件读取4个字节的数据 fread(&filehead->bfReserved1, 2, 1, fp);//从BMP文件读取2个字节的数据 fread(&filehead->bfReserved2, 2, 1, fp);//从BMP文件读取2个字节的数据 fread(&filehead->bfOffBits, 4, 1, fp);//从BMP文件读取4个字节的数据 } fclose(fp); return 1; } /***************************************************************************************/ /**************读取BMP文件的信息头,并保存于infohead指向的区域**************************/ /***************************************************************************************/ int read_bmp_infohead( char* bmpName, BITMAPINFOHEADER* infohead) { FILE* fp; fp=fopen(bmpName, "rb"); if (fp==NULL) { printf("Can't open %s\n",bmpName); return 0; } else fseek(fp, 14, 0);//跳过BMP文件起始的14个字节 fread(infohead, 40, 1, fp);//从BMP文件一次性读取40个字节的数据 fclose(fp); return 1; } /***************************************************************************************/ /*****************读取BMP文件的颜色表,并保存在color数组*********************************/ /***************************************************************************************/ int read_bmp_colortable( char* bmpName, int bitCount, int colorused, RGBQUAD* color) { int colornum; FILE* fp; fp=fopen(bmpName, "rb"); if (fp==NULL) { printf("Can't open %s\n",bmpName); return 0; } if (bitCount==24) { printf("The true color BMP doesn't have color table!\n");//24位的真彩BMP没有颜色表 return 0; } else if (colorused==0)//当BMP信息头的colorused为零时,则颜色表的颜色总数为2的bitCount次幂 { colornum=(int) pow(2, bitCount);//颜色表的颜色总数 fseek(fp, 54, 0); fread(color, 4*colornum, 1, fp); } else { fseek(fp, 54, 0); fread(color, 4*colorused, 1, fp); } fclose(fp); return 1; } /***************************************************************************************/ /********读取BMP文件的位图数据保存到某个二维数组,并返回二维数组的指针******************/ /***************************************************************************************/ BYTE** read_bmpData2array(char* bmpName, int width, int height, int bitCount, int dataoffset) { int totalbytes_line; BYTE** array_pointer; int i, j, k; FILE* fp; fp=fopen(bmpName, "rb");//用"rb"的方式打开一个文件 if (fp==NULL) { printf("Can't open %s\n",bmpName); return 0; } totalbytes_line=(width*bitCount 31)/32*4;//经过补零之后,每一行的总字节数 //给二维数组动态分配内存 array_pointer=(BYTE**) malloc(height*sizeof(BYTE*)); for(k=0; k<height; k ) { array_pointer[k]=malloc(totalbytes_line*sizeof(BYTE)); if(array_pointer[k]==NULL) { printf("The malloc of array_pointer[k] fail", k); } } fseek(fp, dataoffset, 0); for (i=0; i<height; i ) for (j=0; j<totalbytes_line; j ) array_pointer[i][j]=fgetc(fp);//将位图数据按序读到二维数组 fclose(fp); return(array_pointer); } /***************************************************************************************/ /***********************************创建空间滤波的模板**********************************/ /*函数输入为滤波模板的高和宽 /*函数返回值为指向存储模板系数的二维数组的指针 /***************************************************************************************/ BYTE** create_template( int plate_height, int plate_width ) { BYTE** coefficient_array; int i, j; //给二维数组动态分配内存 coefficient_array=(BYTE**) malloc(plate_height*sizeof(BYTE*)); for(i=0; i<plate_height; i ) { coefficient_array[i]=malloc(plate_width*sizeof(BYTE)); if(coefficient_array[i]==NULL) { printf("The malloc of coefficient_array[%d] failed", i); } } //给二维数组赋值,即确定模板的系数 for(i=0; i<plate_height; i ) for(j=0; j<plate_width; j ) { coefficient_array[i][j]=1;//均值滤波模板的系数全为1 } return coefficient_array; } /***************************************************************************************/ /*************************************对图像做对均值滤波********************************/ //函数输入array_pointer为指向存储位图数据的二维数组的指针 //coefficient_array为指向存储滤波模板系数的二维数组的指针 //img_width和img_height分别是待处理BMP图片的高和宽 //plate_width和plate_height分别是滤波模板的高和宽 /***************************************************************************************/ int average_filter(BYTE** array_pointer, BYTE** coefficient_array, DWORD img_width, DWORD img_height, int plate_width, int plate_height) { DWORD i, j; int m, n; float sum_weight, sum_coefficient=0.0f; int distance=(plate_height-1)/2; //滤波模板中心到边界的距离,本实验中plate_width和plate_height相等,且都是奇数 //求滤波模板的系数和 for(m=0; m<plate_height; m ) for(n=0; n<plate_width; n ) { sum_coefficient=sum_coefficient coefficient_array[m][n]; } //对像素点作均值滤波,本实验将滤波模板中心的移动范围限制在距离图像边缘distance个像素处 for(i=distance; i<img_height-distance; i ) for(j=distance; j<img_width-distance; j ) { //每次循环前,将加权和置零 sum_weight=0.0f; //求加权和 for(m=0-(plate_height-1)/2; m<=(plate_height-1)/2; m ) for(n=0-(plate_width-1)/2; n<=(plate_width-1)/2; n ) { sum_weight=sum_weight coefficient_array[distance m][distance n]*array_pointer[i m][j n]; } array_pointer[i][j]=(BYTE) (sum_weight/sum_coefficient 0.5); //求均值滤波的结果,并四舍五入 } return 0; } /***************************************************************************************/ /**********************创建一个新的BMP文件(不含位图数据和颜色表)**********************/ /***************************************************************************************/ int create_blankBmp(char* newbmpName, BITMAPFILEHEADER* filehead, BITMAPINFOHEADER* infohead) { FILE* fp; fp=fopen(newbmpName, "w ");//用"w "的方式新建一个文件,并打开 if (fp==NULL) { printf("Can't open %s\n",newbmpName); return 0; } fwrite(&filehead->bfType, 2, 1, fp);//依次写入文件头信息 fwrite(&filehead->bfSize, 4, 1, fp); fwrite(&filehead->bfReserved1, 2, 1, fp); fwrite(&filehead->bfReserved2, 2, 1, fp); fwrite(&filehead->bfOffBits, 4, 1, fp); fwrite(infohead, 40, 1, fp);//写入信息头信息 fclose(fp); return 1; } /***************************************************************************************/ /*************************向新建BMP文件填充颜色表和位图数据*****************************/ /***************************************************************************************/ int input_color_data(char* newbmpName, BITMAPFILEHEADER* filehead, BITMAPINFOHEADER* infohead, RGBQUAD* color, BYTE** array_pointer) { DWORD h, w, n; FILE* fp; fp=fopen(newbmpName, "rb ");//用"rb "的方式打开已经建立的目标BMP文件 if (fp==NULL) { printf("Can't open %s\n",newbmpName); return 0; } fseek(fp, 54, 0); fwrite(color, 4*256, 1, fp);//先写入颜色表 h=infohead->biHeight;//8位BMP图像的高 w=((infohead->biWidth)*8 31)/32*4;//8位BMP图像的每一行补零之后所占的总字节数 for(n=0; n<h; n ) fwrite(array_pointer[n], w, 1, fp);//写入各个像素的值 fclose(fp); return 1; }
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论