平滑滤波器又叫均值滤波器,可以使图片模糊,去噪。
示例:Unity实现
SmoothFilter.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; // 平滑滤波器 public sealed class SmoothFilter { //定义滤波器模板 private static int MAX_FILTER_X = 3; private static int FILTER_D = 1; private static float[] filter3x3 = new float[] { 1, 1, 1, 1, 1, 1, 1, 1, 1 }; private static float[] filter = filter3x3; // 改变滤波器模板,n必须为奇数(如3、5、7、9、...) // n越大,图像越模糊 public static void ChangeFilterTemplet(int n) { MAX_FILTER_X = n; FILTER_D = (n - 1) / 2; filter = new float[n*n]; for (int i=0; i<filter.Length; i++) filter[i] = 1; } public static Texture2D Apply(Texture2D raw) { int width = raw.width; int height = raw.height; Texture2D smoothTex = new Texture2D(width, height, TextureFormat.ARGB32, false); for (int y=0; y<height; y++) { for (int x=0; x<width; x++) { float r = 0, g = 0, b = 0; //计算模板对应像素区域的颜色之和 for (int py=y-FILTER_D, fy=0; py <= y+FILTER_D; py++, fy++) { for (int px=x-FILTER_D, fx=0; px <= x+FILTER_D; px++, fx++) { Color c = GetRawPixel(raw, px, py); float f = GetFilterValue(fx, fy); r += c.r * f; g += c.g * f; b += c.b * f; } } //求颜色均值 float fd = FilterDenominator; float mean_r = r / fd; float mean_g = g / fd; float mean_b = b / fd; Color mean_c = new Color(mean_r, mean_g, mean_b); SetSmoothPixel(smoothTex, x, y, mean_c); } } smoothTex.Apply(); return smoothTex; } private static Color GetRawPixel(Texture2D raw, int x, int y) { if (x < 0 || y < 0 || x >= raw.width || y >= raw.height) return Color.black; return raw.GetPixel(x, y); } private static void SetSmoothPixel(Texture2D smoothTex, int x, int y, Color mean) { if (x < 0 || y < 0 || x >= smoothTex.width || y >= smoothTex.height) return; smoothTex.SetPixel(x, y, mean); } private static float GetFilterValue(int x, int y) { int i = y * MAX_FILTER_X + x; return filter[i]; } // 模板各元素之和 private static float FilterDenominator { get { float d = 0; for (int i=0; i<filter.Length; i++) d += filter[i]; return d; } } }
TestSmoothFilter.cs
using System; using System.IO; using System.Collections; using System.Collections.Generic; using UnityEngine; // 测试脚本 public class TestSmoothFilter : MonoBehaviour { public Texture2D texture; public Texture2D smoothTexture; void Start () { SmoothFilter.ChangeFilterTemplet(3); smoothTexture = SmoothFilter.Apply(texture); SavePNG("D:/3x3.png", smoothTexture); SmoothFilter.ChangeFilterTemplet(5); smoothTexture = SmoothFilter.Apply(texture); SavePNG("D:/5x5.png", smoothTexture); SmoothFilter.ChangeFilterTemplet(7); smoothTexture = SmoothFilter.Apply(texture); SavePNG("D:/7x7.png", smoothTexture); SmoothFilter.ChangeFilterTemplet(9); smoothTexture = SmoothFilter.Apply(texture); SavePNG("D:/9x9.png", smoothTexture); SmoothFilter.ChangeFilterTemplet(15); smoothTexture = SmoothFilter.Apply(texture); SavePNG("D:/15x15.png", smoothTexture); } public void SavePNG(string filePath, Texture2D texture) { try { byte[] pngData = texture.EncodeToPNG(); File.WriteAllBytes(filePath, pngData); } catch (Exception ex) { Debug.Log(ex.StackTrace); } } }
运行测试
原图
3x3
5x5
7x7
9x9
15x15