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("正在获取数据...... "); 14 FILE *fp ; 15 fp = fopen(cFilePath , "r"); 16 if(NULL == fp) 17 { 18 printf("open file failed! "); 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! "); 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("正在保存数据...... "); 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! "); 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("文件保存成功! "); 71 72 return ; 73 } 74 75 bool JunZhiLvBo(const int nOriginalData[DATA_Y][DATA_X], int nResultData[DATA_Y][DATA_X]) 76 { 77 printf("正在进行均值滤波...... "); 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("操作失败! "); 127 return 0; 128 } 129 130 char cSaveFilePath[] = "Result.raw"; //文件保存路径 131 132 SaveFile(cSaveFilePath,nResultData); 133 134 return 0; 135 }
3 均值滤波算法效果对比
均值滤波之前: 均值滤波之后: