哈哈哈,我这个真是有点慢的。

先来张刘诗诗,用了4秒才出结果

下面是代码~~~

using System;
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// 双边滤波
/// </summary>
public class BilateralFilter<T> where T:TexData,new(){TexData[] originalData,curData;int width, height;//图像宽高double sigma_r, sigma_d;//r,ddouble recip_2r2, recip_2d2;//2sigma平方的倒数/// <summary>/// 预计算空间域权重数组,未计算exp/// </summary>double[,] SpatialWightArray;int len;//窗口长宽int pCent;//窗口中心int depth;double sumWeight;/// <summary>/// 双边滤波/// </summary>/// <param name="texData">实现该接口的类型的数组</param>/// <param name="w">图片宽</param>/// <param name="h">图片高</param>/// <param name="sigma_r">sigma_r</param>/// <param name="sigma_d">sigma_d</param>/// <param name="r">窗口大小 len = 2*r + 1</param>public BilateralFilter(T[] texData,int w,int h,float sigma_r = 0.1f,float sigma_d = 3,int r = 1) {this.originalData = texData as TexData[];this.width = w;this.height = h;this.sigma_r = sigma_r;this.sigma_d = sigma_d;this.recip_2r2 = 1 / (0.5f * sigma_r * sigma_r);this.recip_2d2 = 1 / (0.5f * sigma_d * sigma_d);this.len = r * 2 + 1;pCent = len / 2;this.depth = this.len * this.len;curData = new TexData[texData.Length];Array.Copy(texData, curData, curData.Length);getSpatialWightArray();}/// <summary>/// 滤波/// </summary>public TexData[] Filter() {var tcurData = new TexData[width*height];Array.Copy(curData, tcurData, tcurData.Length);//滑动窗口以滤波for (int j = 0; j < height; j++) {for (int i = 0; i < width; i++) {//计算当前加权窗口double[,] window = new double[len, len];//当前权重窗口TexData tSum = new T();//窗口数据汇总double sumWeight = 0;for (int l = 0; l < len; l++) {for (int k = 0; k < len; k++) {var cent = At(i, j);var cur = At(i, j, k, l);double w1 = SpatialWightArray[k, l];double w2 = similarityWeight(cent, cur);window[k,l] = Math.Exp( w1+ w2);sumWeight += window[k, l];tSum = tSum.ADD(cur.MUL((float)window[k,l]));}}tSum = tSum.DIV((float)sumWeight);tcurData[i+j*width] = tSum;}}curData = tcurData;return curData;}/// <summary>/// 重新设置参数,传入负值则不改动(未实现)/// </summary>public void ResizeParams(float sigma_r,float sigma_d,int r) { }/// <summary>/// 预先计算空间域权重数组/// </summary>protected void getSpatialWightArray() {SpatialWightArray = new double[len,len];for (int k = 0; k < len; k++) {for (int l = 0; l < len; l++) {SpatialWightArray[k, l] = spatialWeight(k, l);}}}/// <summary>/// 空间域权重,未计算exp/// </summary>protected double spatialWeight(int k, int l) {double i_k_2 = Math.Pow(pCent - k, 2);double j_l_2 = Math.Pow(pCent - l, 2);return -(i_k_2 + j_l_2)*recip_2d2;}/// <summary>/// 值域权重,未计算exp/// </summary>protected double similarityWeight(int i, int j, int k, int l) {var cent = At(i, j);var cur = At(i, j, k, l);return similarityWeight(cent,cur); ;}protected double similarityWeight(TexData cent, TexData cur) {float grayij = cent.GetGray();float graykl = cur.GetGray();return -(Math.Pow(Math.Abs(grayij - graykl), 2)) * recip_2r2;}private TexData At(int i,int j) {return At(i,j,pCent,pCent);}/// <summary>/// 窗口内取值/// </summary>/// <returns></returns>private TexData At(int i, int j, int k, int l) {int ti, tj;ti = Clamp(Math.Abs(i + (k - pCent)),0,width-1);tj = Clamp(Math.Abs(j + (l - pCent)),0,height-1);return curData[ti+tj*width];}double Clamp(double v,double min,double max) {if (v < min)return min;else if (v > max)return max;elsereturn v;}int Clamp(int v, int min, int max) {if (v < min)return min;else if (v > max)return max;elsereturn v;}
}
public interface TexData {float R { get; }float G { get; }float B { get; }float A { get; }float GetGray();TexData ADD(TexData other);TexData SUB(TexData other);TexData MUL(float scale);TexData DIV(float scale);}
//以下是U3D部分
public class U3DColor : TexData {private UnityEngine.Color col;public U3DColor() {col = new UnityEngine.Color(1, 1, 1, 1);}public U3DColor(UnityEngine.Color col) {this.col = col;}public float GetGray() {return col.grayscale;}public TexData ADD(TexData other) {return new U3DColor(col + new UnityEngine.Color(other.R, other.G, other.B, other.A));}public TexData SUB(TexData other) {return new U3DColor(col - new UnityEngine.Color(other.R, other.G, other.B, other.A));}public TexData MUL(float scale) {return new U3DColor(col * scale);}public TexData DIV(float scale) {return new U3DColor(col / scale);}public static implicit operator UnityEngine.Color(U3DColor c) {return c.col;}public static implicit operator U3DColor(UnityEngine.Color c) {return new U3DColor(c);}public float R {get { return col.r; }}public float G {get { return col.g; }}public float B {get { return col.b; }}public float A {get { return col.a; }}public override string ToString() {return col.ToString();}
}

然后是一个在U3D的调用测试

using UnityEngine;
using System.Collections;public class Test_BilateralFilter : MonoBehaviour {public Texture2D inTex, outTex,combine;public float sigma_r, sigma_d;// Use this for initializationvoid Start () {Color[] inCol = inTex.GetPixels();U3DColor[] u3dInCol = new U3DColor[inCol.Length];for (int i = 0; i < inCol.Length; i++)u3dInCol[i] = inCol[i];BilateralFilter<U3DColor> bf = new BilateralFilter<U3DColor>(u3dInCol, inTex.width, inTex.height, sigma_r, sigma_d,1);float t = Time.realtimeSinceStartup;TexData[] data = bf.Filter();Color[] outCol = new Color[inCol.Length];for (int i = 0; i < inCol.Length; i++)outCol[i] = data[i] as U3DColor;outTex = new Texture2D(inTex.width,inTex.height);outTex.SetPixels(outCol);outTex.Apply();Debug.LogFormat("用时:{0}", Time.realtimeSinceStartup - t);combine = new Texture2D(2, 2);combine.PackTextures(new Texture2D[] { inTex, outTex },0);}
}

面板拖了一张图:

运行~,就生成outTex和Combine的图片了~~~~~可惜太慢

再来张大窗口的:

稍有改动测试参数,如下:

双边滤波C#及Unity3D龟速实现相关推荐

  1. OpenCV medianBlur、GaussianBlur和bilateralFilter (中值滤波、高斯滤波、双边滤波)

    ::返回OpenCV算子速查表 中值模糊.高斯模糊和双边滤波 1. 函数定义 1.1 中值模糊 1.2 高斯模糊 1.3 双边滤波 2. 例程 1. 函数定义 1.1 中值模糊 OpenCV官方文档 ...

  2. 《OpenCV3编程入门》学习笔记6 图像处理(二)非线性滤波:中值滤波、双边滤波

    第6章 图像处理 6.2 非线性滤波:中值滤波.双边滤波 6.2.1 非线性滤波 很多情况下,使用领域像素的非线性滤波会得到更好的效果,如在噪声是散粒噪声而不是高斯噪声,即图像偶尔会出现很大值时,高斯 ...

  3. 双边滤波算法的简易实现bilateralFilter

    没怎么看过双边滤波的具体思路,动手写一写,看看能不能突破一下. 最后,感觉算法还是要分开 水平 与 垂直 方向进行分别处理,才能把速度提上去. 没耐性写下去了,发上来,给大伙做个参考好了. 先上几张效 ...

  4. (13)中值滤波和双边滤波

    其实中值滤波,就是那九个数值,进行排序,选择中间的数值来代替那九个数的中间位置的值,然后再从左到右,从上到下,这样移动运算 ====================================== ...

  5. matlab 双边沿滤波,图片漫画效果(DoG算子和双边滤波)

    对比下面两张图(从 http://hi.baidu.com/cwyalpha/blog/item/647745a9f33570f61e17a235.html 里翻出来的..),漫画有3个特点: 1.边 ...

  6. Bilateral Filtering(双边滤波) for SSAO(转)

    原文链接:http://blog.csdn.net/bugrunner/article/details/7170471 另外一篇相似的英文资料:http://homepages.inf.ed.ac.u ...

  7. 双边滤波+ 通俗自己理解

    原文:https://blog.csdn.net/qq_36359022/article/details/80198890 原文有图 还有一种解释:https://blog.csdn.net/chen ...

  8. 双边滤波JAVA代码实现

    双边滤波JAVA代码实现 [plain] view plaincopy package test; /** *  A simple and important case of bilateral fi ...

  9. python 双边滤波与高斯滤波

    双边滤波速度不是特别快 python 双边滤波与高斯滤波 高斯滤波就是对整幅图像进行加权平均的过程.每个像素点的值,都由其本身和邻域内的其它像素值经过加权平均后得到.高斯滤波的详细操作是:用一个模板( ...

最新文章

  1. Quorum-based voting
  2. Angular 下拉菜单实现的一个例子
  3. leetcode971. 翻转二叉树以匹配先序遍历(dfs)
  4. vue-cli3使用svg图标的详细步骤
  5. java改变线程堆栈大小,在运行时更新java线程的堆栈大小
  6. 计算机2010ppt试题,计算机Office2010 PPT试题.doc
  7. phpspider 爬取汉谜网
  8. ASCII、Unicode、UTF、base64
  9. 大数据使用的5种主要数据挖掘技术
  10. Tesseract-OCR4.0识别中文与训练字库实例
  11. 杭电2079-选课时间(题目已修改,注意读题)
  12. 非线性回归-最小二乘法
  13. 日本流行语------收录
  14. 学习Linux(centos7)准备的工具
  15. Python 实现ARP与DNS欺骗
  16. Freeswitch挂断原因汇总
  17. 高德地图图片叠加层示例方法的缺点
  18. RTOS系统CPU使用率和任务堆栈空间统计方法
  19. python django签到系统
  20. 应用回归分析pdf网盘_艾媒咨询|2020上半年中国个人网盘市场现状及头部企业布局研究报告...

热门文章

  1. mysql 处理json数组
  2. 如何灵活的实现告警的通知?
  3. 基于ETest开发某型号北斗/GPS接收机测试系统
  4. SDN 软件定义网络
  5. 博客园文章添加版权信息的方法
  6. C - 数据结构实验:哈希表
  7. 【CAN转以太网、车联网怎么实现远程数据监控,远程数据下载详细介绍】
  8. 数字未来,企业董监高会议效率的破局之法
  9. 哈工大操作系统实验坏境搭建
  10. 神印落幕 远去的繁华