#region 二维高斯滤波 //高斯滤波器 private double[,] gaussFilter(int size,double sigma) { double[,] arr=new double[size,size]; double sum = 0.0; int center = size; //以第一个点的坐标为原点,求出中心点的坐标 for (int i = 0; i < size; ++i) for (int j = 0; j < size; ++j) sum += arr[i,j] = Math.Exp(-((i - center)*(i - center) + (j - center)*(j - center)) / (2 * sigma*sigma)); for (int i = 0; i < size; ++i) for (int j = 0; j < size; ++j) arr[i,j] /= sum; return arr; //for (int i = 0; i < size; ++i) { // for (int j = 0; j < size; ++j) // Console.Write(arr[i,j]+" "); // Console.WriteLine(); //} } //高斯滤波算法 private void myGaussFilter(short[,] data) { int w_Data = data.GetLength(0); int h_Data = data.GetLength(1); double[,] arr=gaussFilter(3,1.5); for (int i = 2; i < w_Data-1; i++) { for (int j = 2; j < h_Data-1; j++) { bool judgeBool = false; for (int a = i - 1; a <= i + 1; a++) { for (int b = j - 1; b <= j + 1; b++) { if (Math.Abs(a - i) == 1 || Math.Abs(b - j) == 1) { if (data[a, b] == 0) { judgeBool=true; break; } } } if (judgeBool) { break; } } if (judgeBool) { //if (data[i, j] > 0) //{ // short[,] shortTmp = (short[,])data.Clone(); // data[i, j] = edgeBianTong(shortTmp, new Point(i, j), arr); //} continue; } double tmpValue = 0; for (int x = 0; x < 3; x++) { for (int y = 0; y < 3; y++) { tmpValue += data[i + 1 - x, j + 1 - y] * arr[x, y];//高斯滤波矩阵是对称的 } } data[i, j] = (short)tmpValue; } } } private void myGaussFilter123(short[,] data) { int w_Data = data.GetLength(0); int h_Data = data.GetLength(1); double[,] arr = gaussFilter(3, 1.5); for (int i = 2; i < w_Data - 1; i++) { for (int j = 2; j < h_Data - 1; j++) { bool judgeBool = false; for (int a = i - 1; a <= i + 1; a++) { for (int b = j - 1; b <= j + 1; b++) { if (Math.Abs(a - i) == 1 || Math.Abs(b - j) == 1) { if (data[a, b] == 0) { judgeBool = true; break; } } } if (judgeBool) { break; } } if (judgeBool) { if (data[i, j] > 0) { short[,] shortTmp = (short[,])data.Clone(); data[i, j] = edgeBianTong(shortTmp, new Point(i, j), arr); } continue; } double tmpValue = 0; for (int x = 0; x < 3; x++) { for (int y = 0; y < 3; y++) { tmpValue += data[i + 1 - x, j + 1 - y] * arr[x, y];//高斯滤波矩阵是对称的 } } data[i, j] = (short)tmpValue; } } } //边界变通 private short edgeBianTong(short[,] data, Point point, double[,] arr) { //扩充边界和高斯滤波同时进行 double tmpValue = 0; for (int i = point.X - 1 ,a=0; i <= point.X + 1; i++,a++) { for (int j = point.Y - 1 ,b=0; j <= point.Y + 1; j++,b++) { if (data[i, j] == 0) { data[i, j] = data[point.X,point.Y]; } //tmpValue += data[i, j] * arr[1-Math.Abs(i - point.X), 1-Math.Abs(j - point.Y)]; tmpValue += data[i, j] * arr[a,b]; } } return (short)tmpValue; } #endregion
注:
1.本例子是红外图像做差得到的人体图像,非人体图像温度数值都为0.
2.myGaussFilter123含边界点(未全包含:整幅图像的边界未包含,仅涵盖了图像(不不包括图像边界)中的人体边缘点)。
3.myGaussFilter不含边界点,经测试发现,对边界去毛边并未有区别(也许与自己扩充边界用原值复制相关,有待进一步测试),所以对于整幅图像的边界点不再进行高斯滤波处理了。
4.不过对于颗粒度有点强的图像,用高斯滤波圆润挺好的。