C语言实现图像中值滤波与均值滤波

中值滤波

中值滤波法是一种非线性平滑技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值。中值滤波容易去除孤立点,线的噪声同时保持图象的边缘,对椒盐噪声有较好的滤波效果;它能很好的去除二值噪声,但对高斯噪声无能为力。

实现代码(3x3中值滤波):

#include
#include
#include
#pragma pack(1)   //全紧凑模式

typedef struct {
	unsigned char bfType[2];
	unsigned int bfSize;
	unsigned short bfReserved1;
	unsigned short bfReserved2;
	unsigned int bfOffBits;
}bitmapFileHeader;

typedef struct {
	unsigned int biSize;
	unsigned int biWidth;
	unsigned int biHeight;
	unsigned short biPlanes;
	unsigned short biBitCount;
	unsigned int biCompression;
	unsigned int biSizeImage;
	unsigned int biXPixPerMeter;
	unsigned int biYPixPerMeter;
	unsigned int biClrUsed;
	unsigned int biClrImportant;
}bitmapInfoHeader;


typedef struct{
	unsigned char rgbBlue;
	unsigned char rgbGreen;
	unsigned char rgbRed;
	unsigned char rgbReserved;

}rgbQUAD;

typedef struct{
	bitmapFileHeader bfHeader;
	bitmapInfoHeader biHeader;
	rgbQUAD palette[256];
	unsigned char *imgData;
}bmp;

unsigned char median(unsigned char num[],int m){
	int i,j;
	unsigned char temp;
	for(i=0;i<m;i++){
		for(j=i+1;j<m;j++){
			if(num[j]<num[i]){
				temp=num[i];
				num[i]=num[j];
				num[j]=temp;
			}
		}
	}
	return num[m/2];
}

int main(){
	FILE *fp;
	if((fp=fopen("d:\Temp\\test_gray.bmp","rb"))==NULL){
		perror("can not open file!");
		return -1;
	}
	//读入彩色bmp图像文件头,信息头和图像数据
	bitmapFileHeader bfHeader;
	fread(&bfHeader,14,1,fp);
	bitmapInfoHeader biHeader;
	fread(&biHeader,40,1,fp);
	int imSize=biHeader.biSizeImage;
	int width=biHeader.biWidth;
	int height=biHeader.biHeight;
	int bitCount=biHeader.biBitCount;
	int lineBytes=(width*bitCount+31)/32*4;
	
	fseek(fp,bfHeader.bfOffBits,SEEK_SET);
	unsigned char*imageData=(unsigned char*)malloc(imSize*sizeof(unsigned char));
	fread(imageData,imSize*sizeof(unsigned char),1,fp);	
	fclose(fp);

	bmp b;
	memcpy(&(b.bfHeader),&bfHeader,sizeof(bfHeader));
	memcpy(&(b.biHeader),&biHeader,sizeof(biHeader));
	b.imgData=(unsigned char*)malloc(sizeof(unsigned char)*imSize);
	memset(b.imgData,0,sizeof(unsigned char)*imSize);
	for(int i=0;i<256;i++){
		b.palette[i].rgbBlue=i;
		b.palette[i].rgbGreen=i;
		b.palette[i].rgbRed=i;
	}
	
	int i,j,k;
	unsigned char m=3,n=3;
	unsigned char *row=(unsigned char*)malloc(m);
	unsigned char *col=(unsigned char*)malloc(n);

	int x,y;
	for(i=0;i<height;i++){
		for(j=0;j<width;j++){
			if(j-(m-1)/2>=0&&j+m/2<width&&i-(n-1)/2>=0&&i+n/2<height){
				for(y=0;y<n;y++){
					for(x=0;x<m;x++){
						row[x]=imageData[lineBytes*(i-(n-1)/2+y)+j-(m-1)/2+x];
					}
					col[y]=median(row,m);
				}
				b.imgData[lineBytes*i+j]=median(col,n);
			}
			else
				continue;//b.imgData[lineBytes*i+j]=imageData[lineBytes*i+j];
		}
	}
	
	char savePath[]="D:\Temp\\save_test.bmp";
	FILE *f_save=fopen(savePath,"wb");
	if(f_save==NULL){
		perror("can not open file!");
		return -2;
	}

	fwrite(&b.bfHeader,sizeof(bitmapFileHeader),1,f_save);
	fwrite(&b.biHeader,sizeof(bitmapInfoHeader),1,f_save);
	fwrite(&b.palette,1024,1,f_save);
	fwrite(b.imgData,sizeof(unsigned char)*b.biHeader.biSizeImage,1,f_save);
	fclose(f_save);
	
	free(imageData);
	free(b.imgData);
	getchar();
	return 0;
}


代码效果:

椒盐噪声图像:
C语言实现图像中值滤波与均值滤波_第1张图片中值滤波图像:

C语言实现图像中值滤波与均值滤波_第2张图片

均值滤波

均值滤波是典型的线性滤波算法,它是指在图像上对目标像素给一个模板,该模板包括了其周围的临近像素,再用模板中的全体像素的平均值来代替原来像素值,适用于去除通过扫描得到的图像中的颗粒噪声、高斯噪声。均值滤波本身存在着固有的缺陷,即它不能很好地保护图像细节,在图像去噪的同时也破坏了图像的细节部分,从而使图像变得模糊,不能很好地去除噪声点。

辅助函数:

//求mxn模板中灰值之和
int sum(unsigned char **num, int m, int n){
	int sum=0;
	int i,j;
	for(i=0;i<m;i++){
		for(j=0;j<n;j++){
			sum+=num[i][j];
		}
	}
	return sum;
}

实现代码(3x3均值滤波):

#include
#include
#include
#pragma pack(1)   //全紧凑模式

typedef struct {
	unsigned char bfType[2];
	unsigned int bfSize;
	unsigned short bfReserved1;
	unsigned short bfReserved2;
	unsigned int bfOffBits;
}bitmapFileHeader;

typedef struct {
	unsigned int biSize;
	unsigned int biWidth;
	unsigned int biHeight;
	unsigned short biPlanes;
	unsigned short biBitCount;
	unsigned int biCompression;
	unsigned int biSizeImage;
	unsigned int biXPixPerMeter;
	unsigned int biYPixPerMeter;
	unsigned int biClrUsed;
	unsigned int biClrImportant;
}bitmapInfoHeader;


typedef struct{
	unsigned char rgbBlue;
	unsigned char rgbGreen;
	unsigned char rgbRed;
	unsigned char rgbReserved;

}rgbQUAD;

typedef struct{
	bitmapFileHeader bfHeader;
	bitmapInfoHeader biHeader;
	rgbQUAD palette[256];
	unsigned char *imgData;
}bmp;

int sum(unsigned char **num, int m, int n){
	int sum=0;
	int i,j;
	for(i=0;i<m;i++){
		for(j=0;j<n;j++){
			sum+=num[i][j];
		}
	}
	return sum;
}

int main(){
	FILE *fp;
	if((fp=fopen("d:\Temp\\test_gray.bmp","rb"))==NULL){
		perror("can not open file!");
		return -1;
	}
	//读入彩色bmp图像文件头,信息头和图像数据
	bitmapFileHeader bfHeader;
	fread(&bfHeader,14,1,fp);
	bitmapInfoHeader biHeader;
	fread(&biHeader,40,1,fp);
	int imSize=biHeader.biSizeImage;
	int width=biHeader.biWidth;
	int height=biHeader.biHeight;
	int bitCount=biHeader.biBitCount;
	int lineBytes=(width*bitCount+31)/32*4;
	
	fseek(fp,bfHeader.bfOffBits,SEEK_SET);
	unsigned char*imageData=(unsigned char*)malloc(imSize*sizeof(unsigned char));
	fread(imageData,imSize*sizeof(unsigned char),1,fp);	
	fclose(fp);

	bmp b;
	memcpy(&(b.bfHeader),&bfHeader,sizeof(bfHeader));
	memcpy(&(b.biHeader),&biHeader,sizeof(biHeader));
	b.imgData=(unsigned char*)malloc(sizeof(unsigned char)*imSize);
	memset(b.imgData,0,sizeof(unsigned char)*imSize);
	for(int i=0;i<256;i++){
		b.palette[i].rgbBlue=i;
		b.palette[i].rgbGreen=i;
		b.palette[i].rgbRed=i;
	}
		int i,j,k;
	unsigned char m=3,n=3;
	unsigned char **data=(unsigned char**)malloc(n*sizeof(unsigned char*));
	for(i=0;i<n;i++)
		data[i]=(unsigned char*)malloc(m);

	int x,y;
	for(i=0;i<height;i++){
		for(j=0;j<width;j++){
			if(j-(m-1)/2>=0&&j+m/2<width&&i-(n-1)/2>=0&&i+n/2<height){
				for(y=0;y<n;y++){
					for(x=0;x<m;x++){
						data[y][x]=imageData[lineBytes*(i-(n-1)/2+y)+j-(m-1)/2+x];
					}
				}
				b.imgData[lineBytes*i+j]=sum(data,m,n)/(m*n);
			}
			else
				continue;//b.imgData[lineBytes*i+j]=imageData[lineBytes*i+j];
		}
	}
	
	char savePath[]="D:\Temp\\save_test.bmp";
	FILE *f_save=fopen(savePath,"wb");
	if(f_save==NULL){
		perror("can not open file!");
		return -2;
	}

	fwrite(&b.bfHeader,sizeof(bitmapFileHeader),1,f_save);
	fwrite(&b.biHeader,sizeof(bitmapInfoHeader),1,f_save);
	fwrite(&b.palette,1024,1,f_save);
	fwrite(b.imgData,sizeof(unsigned char)*b.biHeader.biSizeImage,1,f_save);
	fclose(f_save);
	
	free(imageData);
	free(b.imgData);
	getchar();
	return 0;
}


代码效果:

高斯噪声图像:

C语言实现图像中值滤波与均值滤波_第3张图片
均值滤波图像:

C语言实现图像中值滤波与均值滤波_第4张图片

你可能感兴趣的:(数字图像处理,计算机视觉)