[算法说明]
Sigma平滑滤波器是构造一个模板,比如3*3大小的模板,计算这个模板对应的像素的标准差d,然后根据统计学原理,得到一个置信区间v,假设3*3模板中心像素为p,则v大小范围为[p-d,p+d]。
我们判断3*3模板中对应像素是否落在置信区间v内,对于在v内的像素,我们求取他们的均值,然后,当前模板对应的中心像素的滤波值就等于这个均值。
图像表示如下:
/// <summary> /// Sigma filter. /// </summary> /// <param name="src">The source image.</param> /// <returns></returns> public static WriteableBitmap SigmaFilterProcess(WriteableBitmap src)////Sigma滤波器 { if (src != null) { int w = src.PixelWidth; int h = src.PixelHeight; WriteableBitmap filterImage = new WriteableBitmap(w, h); byte[] temp = src.PixelBuffer.ToArray(); byte[] tempMask = (byte[])temp.Clone(); double[] Gray = new double[9]; double variance = 0; int count = 0; for (int j = 1; j < h - 1; j++) { for (int i = 1; i < w - 1; i++) { variance = 0; count = 0; int[] B = new int[9] { tempMask[i * 4 + j * w * 4], tempMask[(i - 1) * 4 + (j - 1) * w * 4], tempMask[i * 4 + (j - 1) * w * 4], tempMask[(i + 1) * 4 + (j - 1) * w * 4], tempMask[(i - 1) * 4 + j * w * 4], tempMask[(i + 1) * 4 + j * w * 4], tempMask[(i - 1) * 4 + (j + 1) * w * 4], tempMask[i * 4 + (j + 1) * w * 4], tempMask[(i + 1) * 4 + (j + 1) * w * 4] }; int[] G = new int[9] { tempMask[i * 4 + 1 + j * w * 4], tempMask[(i - 1) * 4 + 1 + (j - 1) * w * 4], tempMask[i * 4 + 1 + (j - 1) * w * 4], tempMask[(i + 1) * 4 + 1 + (j - 1) * w * 4], tempMask[(i - 1) * 4 + 1 + j * w * 4], tempMask[(i + 1) * 4 + 1 + j * w * 4], tempMask[(i - 1) * 4 + 1 + (j + 1) * w * 4], tempMask[i * 4 + 1 + (j + 1) * w * 4], tempMask[(i + 1) * 4 + 1 + (j + 1) * w * 4] }; int[] R = new int[9] { tempMask[i * 4 + 2 + j * w * 4], tempMask[(i - 1) * 4 + 2 + (j - 1) * w * 4], tempMask[i * 4 + 2 + (j - 1) * w * 4], tempMask[(i + 1) * 4 + 2 + (j - 1) * w * 4], tempMask[(i - 1) * 4 + 2 + j * w * 4], tempMask[(i + 1) * 4 + 2 + j * w * 4], tempMask[(i - 1) * 4 + 2 + (j + 1) * w * 4], tempMask[i * 4 + 2 + (j + 1) * w * 4], tempMask[(i + 1) * 4 + 2 + (j + 1) * w * 4] }; for (int n = 0; n < 9; n++) { Gray[n] = (double)B[n] * 0.114 + (double)G[n] * 0.587 + (double)R[n] * 0.299; } for (int m = 0; m < 9; m++) { variance += ((double)Gray[m] - Gray.Average()) * ((double)Gray[m] - Gray.Average()) / 9; } variance = Math.Sqrt(variance); for (int m = 0; m < 9; m++) { if (Gray[m] < Gray[0]-variance && Gray[m] > variance + Gray[0]) { R[m] = 0; G[m] = 0; B[m] = 0; } else count++; } temp[i * 4 + j * w * 4] = (byte)(B.Sum() / count); temp[i * 4 + 1 + j * w * 4] = (byte)(G.Sum() /count); temp[i * 4 + 2 + j * w * 4] = (byte)(R.Sum() / count); } } Stream sTemp = filterImage.PixelBuffer.AsStream(); sTemp.Seek(0, SeekOrigin.Begin); sTemp.Write(temp, 0, w * 4 * h); return filterImage; } else { return null; } }