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

中值滤波

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

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

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#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;
}


代码效果:

椒盐噪声图像:
在这里插入图片描述中值滤波图像:

在这里插入图片描述

均值滤波

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

辅助函数:

//求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<stdio.h>
#include<stdlib.h>
#include<string.h>
#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;
}


代码效果:

高斯噪声图像:

在这里插入图片描述
均值滤波图像:

在这里插入图片描述

  • 19
    点赞
  • 117
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值