1 均值滤波介绍
滤波是滤波是将信号中特定波段频率滤除的操作,是从含有干扰的接收信号中提取有用信号的一种技术。
均值滤波是典型的线性滤波算法,它是指在图像上对目标像素给一个模板,该模板包括了其周围的临近像素(如3×3模板:以目标象素为中心的周围8个象素,构成一个滤波模板,即去掉目标象素本身),再用模板中的全体像素的平均值来代替原来像素值。
均值滤波效果:平滑线性滤波处理降低了图像的“尖锐”变化。由于典型的随机噪声由灰度级的急剧变化组成,因此常见的平滑处理的应用就是降低噪声。均值滤波器的主要应用是去除图像中的不相关细节,其中“不相关”是指与滤波器模板尺寸相比较小的像素区域。然而,由于图像的边缘也是由图像灰度的尖锐变化带来的特性,所以均值滤波处理还是存在着边缘模糊的负面效应。
2 均值滤波算法实现(C语言)
1 // junzhilvbo.cpp : 定义控制台应用程序的入口点。
2 //
3
4 #include "stdafx.h"
5 #include "stdlib.h"
6 #include "string.h"
7
8 #define DATA_X 256 //数字图像水平像素个数
9 #define DATA_Y 256 //数字图像竖直像素个数
10
11 void OpenFile(const char *cFilePath , int nOriginalData[DATA_Y][DATA_X])
12 {
13 printf("正在获取数据......\n");
14 FILE *fp ;
15 fp = fopen(cFilePath , "r");
16 if(NULL == fp)
17 {
18 printf("open file failed! \n");
19 return ;
20 }
21
22 unsigned char *pData = (unsigned char *)malloc(sizeof(unsigned char)*DATA_X*DATA_Y);
23 if(NULL == pData)
24 {
25 printf("memory malloc failed!\n");
26 return ;
27 }
28
29 fread(pData , sizeof(unsigned char)*DATA_X*DATA_Y , 1 , fp);
30
31 int count_x = 0 ;
32 int count_y = 0 ;
33
34 for(;count_y < DATA_Y ; count_y++)
35 {
36 for(; count_x < DATA_X ;count_x++)
37 {
38 nOriginalData[count_y][count_x] = pData[count_y*DATA_Y+count_x];
39 }
40 }
41
42 free(pData);
43 fclose(fp);
44
45 return ;
46 }
47
48 void SaveFile(const char *cFilePath , int nResultData[DATA_Y][DATA_X])
49 {
50 printf("正在保存数据......\n");
51 int count_x,count_y;
52
53 FILE *fp ;
54 fp = fopen(cFilePath , "w");
55 if(NULL == fp)
56 {
57 printf("open file failed! \n");
58 return ;
59 }
60
61 for(count_y=0;count_y<DATA_Y;count_y++)
62 {
63 for(count_x=0;count_x<DATA_X;count_x++)
64 {
65 fwrite(&nResultData[count_y][count_x],1,1,fp);
66 }
67 }
68
69 fclose(fp);
70 printf("文件保存成功! \n");
71
72 return ;
73 }
74
75 bool JunZhiLvBo(const int nOriginalData[DATA_Y][DATA_X], int nResultData[DATA_Y][DATA_X])
76 {
77 printf("正在进行均值滤波......\n");
78 int count_x ,count_y ;
79
80 /*3*3模版滤波计算,不计算边缘像素*/
81 for(count_y = 1 ; count_y < DATA_Y ; count_y++)
82 {
83 for(count_x = 1 ; count_x < DATA_X ;count_x++)
84 {
85 nResultData[count_y][count_x] = (int)((nOriginalData[count_y-1][count_x-1]+
86 nOriginalData[count_y-1][count_x] +
87 nOriginalData[count_y-1][count_x+1]+
88 nOriginalData[count_y][count_x-1] +
89 nOriginalData[count_y][count_x] +
90 nOriginalData[count_y][count_x+1] +
91 nOriginalData[count_y+1][count_x-1]+
92 nOriginalData[count_y+1][count_x] +
93 nOriginalData[count_y+1][count_x+1])/9);
94 }
95 }
96
97 /*对四个边缘直接进行赋值处理*/
98 for(count_x=0;count_x<DATA_X;count_x++) //水平边缘像素等于原来像素灰度值
99 {
100 nResultData[0][count_x]=nOriginalData[0][count_x];
101 nResultData[DATA_Y-1][count_x]=nOriginalData[DATA_Y-1][count_x];
102 }
103 for(count_y=1;count_y<DATA_Y-1;count_y++) //竖直边缘像素等于原来像素灰度值
104 {
105 nResultData[count_y][0]=nOriginalData[count_y][0];
106 nResultData[count_y][DATA_X-1]=nOriginalData[count_y][DATA_X-1];
107 }
108
109 return true ;
110 }
111
112 int _tmain(int argc, _TCHAR* argv[])
113 {
114 int nOriginalData[DATA_Y][DATA_X]; //保存原始图像灰度值
115 int nResultData[DATA_Y][DATA_X]; //保存滤波后的灰度值
116
117 memset(nOriginalData,0,sizeof(nOriginalData)); //初始化数组
118 memset(nResultData,0,sizeof(nResultData));
119
120 char cOpenFilePath[] = "Lena.raw"; //图像文件路径
121
122 OpenFile(cOpenFilePath,nOriginalData);
123
124 if(!JunZhiLvBo(nOriginalData,nResultData)) //滤波计算
125 {
126 printf("操作失败!\n");
127 return 0;
128 }
129
130 char cSaveFilePath[] = "Result.raw"; //文件保存路径
131
132 SaveFile(cSaveFilePath,nResultData);
133
134 return 0;
135 }
3 均值滤波算法效果对比
均值滤波之前: 均值滤波之后: