平滑滤波器又叫均值滤波器,可以使图片模糊,去噪。
示例: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