标签:
二维高斯模糊比较费效率, 一般采用2次一维高斯模糊进行叠加,得到最终的效果图。
具体原理可以参加http://blog.csdn.net/zddblog/article/details/7450033
在unity中做背景模糊的时候可以使用这种算法
private UITexture texture; private float[] gaussianTemplate; private int gaussianSize = 0; public Camera _mainCam; public Camera _uiCam; public int width = 256; //待处理的原图的大小,越小越省内存 public int height = 144; public float sigma = 3.0f; //平滑层度 // Use this for initialization void Start () { texture = GetComponent<UITexture>(); } void GetGaussianTemplate() //高斯模糊有效像素矩阵范围为 (+- 3sigma) 矩阵大小为 (6*sigma + 1) * (6*sigma + 1),利用2次一维高斯分布做叠加,加快运算 { int size = Mathf.CeilToInt(3 * sigma) * 2 + 1; gaussianSize = size; gaussianTemplate = new float[size]; float scale = -0.5f / (sigma * sigma); const float PI = 3.1415926f; float cons = 1/Mathf.Sqrt(-scale/PI); float sum = 0; int center = size / 2; for (int i = 0; i < size; i++) { int x = i - center; gaussianTemplate[i] = cons * Mathf.Exp(x * x * scale); sum += gaussianTemplate[i]; } for (int i = 0; i < size; i++) //归一化矩阵 { gaussianTemplate[i] /= sum; } } // Update is called once per frame void Update () { } void OnGUI() { if (GUI.Button(new Rect(Screen.width/2,0,100,20),"GuassBlur")) { GetGaussianTemplate(); StartCoroutine(UpdatePNG()); } } IEnumerator UpdatePNG() { yield return new WaitForEndOfFrame(); RenderTexture rt = new RenderTexture(width, height, 16, RenderTextureFormat.ARGB32); _mainCam.targetTexture = rt; _mainCam.Render(); _uiCam.targetTexture = rt; _uiCam.Render(); RenderTexture.active = rt; Texture2D _tex = new Texture2D(width, height, TextureFormat.RGB24, false); _tex.ReadPixels(new Rect(0, 0, width, height), 0, 0); _tex.Apply(); _mainCam.targetTexture = null; _uiCam.targetTexture = null; RenderTexture.active = null; GuassBlur(_tex); } void GuassBlur(Texture2D tex) { Texture2D des = new Texture2D(tex.width, tex.height, TextureFormat.RGB24, false); Texture2D temp = new Texture2D(tex.width, tex.height, TextureFormat.RGB24, false); int center = gaussianSize / 2; for (int i = 0; i < tex.height; i++) { for (int j = 0; j < tex.width; j++) { Color acc = new Color(0, 0, 0); float sum = 0; for (int k = -center; k < center; k++) { int pos = j + k; if (pos >= 0 && pos < tex.width) { acc += tex.GetPixel(pos, i) * gaussianTemplate[k + center]; sum += gaussianTemplate[k + center]; } } temp.SetPixel(j, i, acc / sum); } } for (int i = 0; i < tex.width; i++) { for (int j = 0; j < tex.height; j++) { Color acc = new Color(0, 0, 0); float sum = 0; for (int k = -center; k < center; k++) { int pos = j + k; if (pos >= 0 && pos < tex.height) { acc += temp.GetPixel(i, pos) * gaussianTemplate[k + center]; sum += gaussianTemplate[k + center]; } } des.SetPixel(i, j, acc / sum); } } des.Apply(); texture.mainTexture = des; }
算法部分可以参见上面的网址,width和height用于内存控制和加快运算速度,sigma越大,越平滑,执行时间也越长。
标签:
原文地址:http://www.cnblogs.com/yerongsc/p/4335654.html