精华内容
下载资源
问答
  • 主动降噪算法FXLMS

    2020-09-11 23:18:05
    FXLMS主动降噪脚本,可实现多通道降噪,对噪声进行主动控制,实现目标位置噪声下降,实现简单且运算量小,对噪声实现实时控制。
  • 所有声音都是由一定的频谱组成,主动降噪技术的基本原理是对已经存在的噪声进行主动对抗和消除,与传统被动防御降噪不同,主动降噪技术通过技术手段,生成一组与所要消除的噪声相位相等的反相声波,将噪音中和,达到...
  • 一个运算量很小的C语言降噪算法,运算量小,从开源工程中提取出来的
  • 自适应滤波降噪算法

    2019-03-01 16:02:37
    lms, 降噪。自适应滤波算法从某种角度也被称为性能表面搜索法,在性能曲面中,它是通过不断测量一个点是否接近目标值,来寻找最优解。
  • 一种基于运动补偿的3D视频降噪算法,龙红梅,田逢春,在视频图像降噪中,时域滤波比空域滤波在保护边缘和细节,提高PSNR方面更具有优势。根据此原理, 本文中提出了一种基于运动补偿的3D�
  • BM3D降噪算法

    2017-10-23 14:46:19
    block-match denoising algorithm,BM3D降噪算法matlab实现
  • 提出了一种基于仿生小波变换和模糊推理的变步长自适应滤波语音降噪算法。该算法首先用仿生小波变换法对包含噪声的语音信号进行小波分解,以分离出来的噪声信号作为自适应滤波器的输入,选择基于模糊推理变步长自适应...
  • 3D 的混合降噪算法是利用区域块 运动 估算的方式,找出前后视频帧中相似 的区域块,使用这些区域块的资料信息进行分析 ,更为准确的分离出图像中的背 景与非背景,并且将背景区域块做 2D 降噪后与运动补偿所得到的...
  • LEE图像降噪算法讲义

    2015-05-30 13:57:04
    LEE图像降噪算法,一个优秀的图像降噪算法
  • 小波阈值降噪算法(C#)

    2018-07-23 19:51:37
    可支持DB1~DB10的小波阈值降噪,在MyWaveletDenoise中的样例为对数据的降噪,输入输出保存在txt文件中。同时支持2D小波降噪等。
  • 针对监控视频图像的特点,提出了一种基于时空联合的实时视频降噪算法。该算法通过结合多帧图像进行运动检测,自适应地区分图像的运动区域和静止区域,对静止区域采用时域加权均值滤波,对运动区域采用空域ANL滤波。...
  • 本论文提出了3D 基于空域和时域混合去除噪声的演算法,此算法包含了2D 的自适应可调式参数分频降噪算法以及3D 混合降噪算法。2D 的可 调式参数降噪算法主要利用时间域为频域中所有频域叠加的原理,以及在各分频中...
  • 图像降噪算法——时域降噪算法

    千次阅读 2020-09-13 09:06:55
    图像降噪算法——时域降噪算法图像降噪算法——时域降噪算法 图像降噪算法——时域降噪算法

    图像降噪算法——时域降噪算法

    最近在工作上接触到了时域降噪相关的算法,这里进行一个简单的总结。我们可以这样理解降噪算法,降噪的过程其实就是通过观测减小噪声方差的过程,对于单帧降噪,做法可以是通过在图片上寻找类似的像素,通过加权平均来获得减少噪声的方差,最经典的就是非局部均值滤波算法,而对于时域降噪,这个概念就更加直接,例如我在第一帧我看到这个像素值是200,第二帧我看到这个像素值是100,第三帧这个像素值是180,第四帧这个像素是190,那么这个像素就就更有可能是180而不是100。

    在时域降噪算法中,最重要的两个步骤分别是对齐融合,下面我分享两篇论文来对这个过程进行解析.

    1.《MeshFLow Video Denoising》

    这是2016年的一篇paper,这篇论文实现的Mesh FLow是基于Homography FLow实现的,Homography FLow的实现可以参考论文《Fast Burst Image Denoising》,所谓Homograhpy Flow就是将图像帧划分为一个个节点,然后通过求解单应矩阵描述不同帧节点与节点之间的变换关系,然后通过单应矩阵来对齐像素,数学原理和SLAM的前端是类似的。Mesh Flow的流程图如下:
    在这里插入图片描述
    根据Mesh FLow的运动模型对齐步骤如下:
    (1)预处理:输入图片后将图片进行网格划分,把每网格的角点当做节点;
    (2)特征点追踪:通过KLT光流法对前后帧之间的特征点进行追踪;
    (3)运动求解:首先通过追踪到的特征求取前后帧的全局单应矩阵,通过全局单应矩阵将前一阵节点的位置投影到当前帧,然后将当前帧上距离节点小于一定阈值的特征点的运动向量存储该到节点的运动向量Buffer,然后对运动向量的Buffer进行中值滤波,将中值滤波后的结果当做节点的运动向量;
    (4)运动滤波:对节点和距离该节点小于一定阈值的节点的运动向量放到Buffer中进行中值滤波,将中值滤波的结果当做该节点的运动向量;
    (5)构建映射:遍历所有网格,利用网格的四个节点的运动向量求解该网格运动的单应矩阵,然后利用该单应矩阵构建网格内若有像素的映射图,即根据给像素的位置查询映射图就可以知道该像素在下一帧的位置;
    (6)像素对齐:根据映射图对齐像素位置,由于该算法中是利用多帧对齐,所以中间还有一步是将映射图叠加,构建不同帧之间的累加运动的映射图。

    像素对齐之后就是进行融合,该算法融合的步骤非常简单,就是对齐后不同帧之间像素灰度值差小于一定阈值的像素进行平均作为当前帧的灰度值,这种简单的融合在灰度变化明显的区域容易造成”坏点“。

    该算法较为简单,而且有开源代码,开源代码中是将所有图片全部读回来再一起处理,改成实时读图片的接口也不难,另外个人觉得可以优化的几点是:
    (1)在特征点追踪是不一定要使用光流法,KLT光流的鲁棒性有限,可以试试ORB特征点说不定在噪声环境下能有更好的下过;
    (2)融合可以结合空域滤波进行优化,例如某一个像素在对齐之后前后帧的像素都不满足像素差阈值可以直接对该像素进行空域滤波,这样可以减少”坏点“的存在;
    (3)算法是多帧融合,相机运动较快时”鬼影“现象是不可避免的。

    2. 《Real-Time Video Denoising On Mobile Phones》

    这是2018年的一篇Paper,这篇论文是基于DIS稠密光流实现的,是Google Pixel 2相机上硬件实现的算法,相较上一篇论文实现更复杂,该算法流程图如下:在这里插入图片描述
    该算法的对齐部分是根据DIS稠密光流算法,这里先介绍DIS稠密光流,DIS稠密光流参考论文《Fast Optical Flow using Dense Inverse Search》。
    DIS稠密光流法首先将图像进行网格划分成图像块,然后构建金字塔,然后对图像金字塔逐层进行图像块的光流追踪,每一层光流由上一层的光流进行初始化。下面详细介绍下DIS稠密光流中使用的逆向组合算法。对于参考帧 I t I_{t} It中的一个图像块 T T T,设其尺寸为 θ p s × θ p s \theta_{p s} \times \theta_{p s} θps×θps,坐标位置为 x = ( x , y ) T \mathbf{x}=(x, y)^{T} x=(x,y)T,我们需要使用梯度下降法在帧 I t + 1 I_{t+1} It+1寻找到最佳匹配的尺寸同样为 θ p s × θ p s \theta_{p s} \times \theta_{p s} θps×θps的图像块,实际上就是寻找一个运动向量 u = ( u , v ) \mathbf{u}=(u, v) u=(u,v)使得前后帧的图像块平方差最小: u = argmin ⁡ u ′ ∑ x [ I t + 1 ( x + u ′ ) − T ( x ) ] 2 \mathbf{u}=\operatorname{argmin}_{\mathbf{u}^{\prime}} \sum_{x}\left[I_{t+1}\left(\mathbf{x}+\mathbf{u}^{\prime}\right)-T(\mathbf{x})\right]^{2} u=argminux[It+1(x+u)T(x)]2例如LK光流就是将其作为一个非线性优化问题,运动向量 u = ( u , v ) \mathbf{u}=(u, v) u=(u,v)作为优化变量,使用迭代法进行求解。在DIS稠密光流中对该方法进行了修改。DIS稠密光流将优化的目标修改为当前运动估计 u \mathbf{u} u基础上的一个更新向量 Δ u \Delta \mathbf{u} Δu Δ u = argmin ⁡ Δ u ′ ∑ x [ I t + 1 ( x + u + Δ u ′ ) − T ( x ) ] 2 \Delta \mathbf{u}=\operatorname{argmin}_{\Delta \mathbf{u}^{\prime}} \sum_{x}\left[I_{t+1}\left(\mathbf{x}+\mathbf{u}+\Delta \mathbf{u}^{\prime}\right)-T(\mathbf{x})\right]^{2} Δu=argminΔux[It+1(x+u+Δu)T(x)]2进一步地将上式的目标损失函数修改为 ∑ x [ T ( x − Δ u ) − I t + 1 ( x + u ) ] 2 \sum_{x}\left[T(\mathbf{x}-\Delta \mathbf{u})-I_{t+1}(\mathbf{x}+\mathbf{u})\right]^{2} x[T(xΔu)It+1(x+u)]2再进行求解,修改成这样有什么好处呢?这样的修改方便我们实现LK光流的逆向组成算法,为了进一步理解逆向组成算法的流程,我们先对目标损失函数进行进一步分解:
    我们先将上式改写为: ∑ x [ T ( W ( x ; Δ u ) ) − I t + 1 ( W ( x ; u ) ) ] 2 \sum_{x}\left[T(\mathbf{W}(\mathbf{x} ; \Delta \mathbf{u}))-I_{t+1}(\mathbf{W}(\mathbf{x} ; \mathbf{u}))\right]^{2} x[T(W(x;Δu))It+1(W(x;u))]2其中 W ( x ; u ) \mathbf{W}(\mathbf{x} ; \mathbf{\mathbf{u}}) W(x;u)描述的是一种映射关系 W ( x ; u ) = ( x − u y − v ) \mathbf{W}(\mathbf{x} ; \mathbf{\mathbf{u}})=\left(\begin{array}{l} x-u \\ y-v \end{array}\right) W(x;u)=(xuyv)我们对上式进行一阶泰勒展开有: ∑ x [ T ( W ( x ; 0 ) ) + ∇ T ∂ W ∂ u Δ u − I t + 1 ( W ( x ; u ) ) ] 2 \sum_{x}\left[T(\mathbf{W}(\mathbf{x} ; \mathbf{0}))+\nabla T \frac{\partial \mathbf{W}}{\partial \mathbf{u}} \Delta \mathbf{u}-I_{t+1}(\mathbf{W}(\mathbf{x} ; \mathbf{u}))\right]^{2} x[T(W(x;0))+TuWΔuIt+1(W(x;u))]2其中 ∇ T \nabla T T为图像块 T T T梯度图像, ∂ W / ∂ u {\partial \mathbf{W}}/{\partial \mathbf{u}} W/u u = 0 \mathbf{u}=\mathbf{0} u=0时的雅克比。为对上式求导,并令导数等于0,得到下式: 2 ∑ x [ ∇ T ∂ W ∂ u ] T [ T ( W ( x ; 0 ) ) + ∇ T ∂ W ∂ u Δ u − I t + 1 ( W ( x ; u ) ) ] = 0 2 \sum_{x}\left[\nabla T \frac{\partial \mathbf{W}}{\partial \mathbf{u}}\right]^{T}\left[T(\mathbf{W}(\mathbf{x}; \mathbf{0}))+\nabla T \frac{\partial \mathbf{W}}{\partial \mathbf{u}} \Delta \mathbf{u}-I_{t+1}(\mathbf{W}(\mathbf{x} ; \mathbf{u}))\right]=0 2x[TuW]T[T(W(x;0))+TuWΔuIt+1(W(x;u))]=0上式对 Δ u \Delta \mathbf{u} Δu进行求解,得到 Δ u \Delta \mathbf{u} Δu的解析解为: Δ u = H − 1 ∑ x [ ∇ T ∂ W ∂ u ] T [ T ( W ( x ; 0 ) ) − I t + 1 ( W ( x ; u ) ) ] \Delta \mathbf{u}=H^{-1} \sum_{x}\left[\nabla T \frac{\partial \mathbf{W}}{\partial \mathbf{u}}\right]^{T}[T(\mathbf{W}(\mathbf{x}; \mathbf{0}))-I_{t+1}(\mathbf{W}(\mathbf{x}; \mathbf{u}))] Δu=H1x[TuW]T[T(W(x;0))It+1(W(x;u))]其中 H = ∑ x [ ∇ T ∂ W ∂ u ] T [ ∇ T ∂ W ∂ u ] H=\sum_{x}\left[\nabla T \frac{\partial \mathbf{W}}{\partial \mathbf{u}}\right]^{T}\left[\nabla T \frac{\partial \mathbf{W}}{\partial \mathbf{u}}\right] H=x[TuW]T[TuW]由于 ∂ W / ∂ u {\partial \mathbf{W}}/{\partial \mathbf{u}} W/u u = 0 \mathbf{u}=\mathbf{0} u=0时的雅克比, ∇ T \nabla T T为梯度图像块 T T T的梯度图像,这两者都是定值,因此矩阵 H H H也是定值,这样就免去了我们在迭代优化 Δ u \Delta \mathbf{u} Δu时反复求解 H H H矩阵的问题。对上面这段推导有点懵逼的同学可以参考下论文《Lucas-Kanade 20 Years On: A Unifying Framework》,这篇论文将光流法总结为四种方法,按照更新量的不同分为additional和compositional两种,按照更新方式不同分为forward和inverse两种,上面推导的这种inverse ccompositional(逆向组成)算法是其中一种。
    在完成图像块的光流追踪之后,当前帧中的像素可能被参考帧中的多个图像块覆盖,我们对所有覆盖该像素的图像块光流进行加权平均就获得该点的光流值: U s ( x ) = 1 Z ∑ i N s λ i , x max ⁡ ( 1 , ∥ d i ( x ) ∥ 2 ) ⋅ u i \mathbf{U}_{s}(\mathbf{x})=\frac{1}{Z} \sum_{i}^{N_{s}} \frac{\lambda_{i, \mathbf{x}}}{\max \left(1,\left\|d_{i}(\mathbf{x})\right\|_{2}\right)} \cdot \mathbf{u}_{i} Us(x)=Z1iNsmax(1,di(x)2)λi,xui其中 u i \mathbf{u}_{i} ui为图像块的光流, U s ( x ) \mathbf{U}_{s}(\mathbf{x}) Us(x)为像素 x \mathbf{x} x处的光流大小, d i ( x ) = I t + 1 ( x + u i ) − T ( x ) d_{i}(\mathbf{x})=I_{t+1}\left(\mathbf{x}+\mathbf{u}_{i}\right)-T(\mathbf{x}) di(x)=It+1(x+ui)T(x),在实现过程中还有一步Variational refinement的过程,但是这一步不是必要的,在OpenCV的实现中这一步也是一个可选项,在此就不进行详细介绍,说道OpenCV,在OpenCV4.0中集成了DIS光流算法,如果大家想复现这个时域降噪算法,可以继承OpenCV4.0中的DIS稠密光流类来进一步实现。

    以上将了该时域降噪算法中对齐部分使用的DIS稠密光流算法,接下来该算法是如何进行融合的,有两点是值得注意的:
    (1)通过高斯金字塔求解DIS光流法,通过拉普拉斯金字塔进行融合
    还不了解拉普拉斯金字塔的同学可以自行百度下,拉普拉斯金字塔可以无损地恢复原始图像,相对直接使用高斯金字塔进行融合显然能保留更多细节
    (2)使用前一帧的降噪结果和当前帧进行融合,通过设计融合权重保证正确性
    首先进行像素对齐 L a l ( p ) = L p l ( p + A l ( p ) ) \mathcal{L}_{a}^{l}(\mathbf{p})=\mathcal{L}_{p}^{l}\left(\mathbf{p}+A^{l}(\mathbf{p})\right) Lal(p)=Lpl(p+Al(p))其中 L a l ( p ) \mathcal{L}_{a}^{l}(\mathbf{p}) Lal(p)为第 l l l层对齐的拉普拉斯金字塔,融合公式为: L r l ( p ) = I c ( p ) ⋅ L c l ( p ) + I p ( p ) ⋅ L a l ( p ) \mathcal{L}_{r}^{l}(\mathbf{p})=\mathcal{I}_{c}(\mathbf{p}) \cdot \mathcal{L}_{c}^{l}(\mathbf{p})+\mathcal{I}_{p}(\mathbf{p}) \cdot \mathcal{L}_{a}^{l}(\mathbf{p}) Lrl(p)=Ic(p)Lcl(p)+Ip(p)Lal(p)我们定义 L Δ l ( p ) = L c l ( p ) − L a l ( p ) \mathcal{L}_{\Delta}^{l}(\mathbf{p})=\mathcal{L}_{c}^{l}(\mathbf{p})-\mathcal{L}_{a}^{l}(\mathbf{p}) LΔl(p)=Lcl(p)Lal(p),那么最终的融合公式变为: L r l ( p ) = w c l ⋅ L c l ( p ) + w p l ⋅ ( L a l ( p ) + I ⋅ L Δ l ( p ) ) \mathcal{L}_{r}^{l}(\mathbf{p})=w_{c}^{l} \cdot \mathcal{L}_{c}^{l}(\mathbf{p})+w_{p}^{l} \cdot\left(\mathcal{L}_{a}^{l}(\mathbf{p})+\mathcal{I} \cdot \mathcal{L}_{\Delta}^{l}(\mathbf{p})\right) Lrl(p)=wclLcl(p)+wpl(Lal(p)+ILΔl(p)) 其中 w c l w_{c}^{l} wcl w p l w_{p}^{l} wpl两个系数用于控制降噪强度, w c l w_{c}^{l} wcl越大细节保留越好, w p l w_{p}^{l} wpl越大降噪强度越大,为了同时保留好的图像细节以及降噪强度要求 w c l + w p l ≥ 1 w_{c}^{l}+w_{p}^{l} \geq 1 wcl+wpl1
    系数 I \mathcal{I} I存在的目的主要是为了消除由于图像像素没有完全对齐进行融合而造成的"鬼影"问题,系数 I \mathcal{I} I的取值范围是 [ 0 , 1 ] [0,1] [0,1],系数 I \mathcal{I} I越大则降噪强度越小,在本算法中,将系数 I \mathcal{I} I定义为 I = max ⁡ ( I e , I Δ ) \mathcal{I}=\max \left(\mathcal{I}_{e}, \mathcal{I}_{\Delta}\right) I=max(Ie,IΔ),其中 I e \mathcal{I}_{e} Ie是和对齐误差有关, I Δ \mathcal{I}_{\Delta} IΔ和像素误差有关,其中 I e = max ⁡ ( 1 , A e l ( p ) ⋅ C e ) \mathcal{I}_{e}=\max \left(1, A_{e}^{l}(\mathbf{p}) \cdot C_{e}\right) Ie=max(1,Ael(p)Ce)其中 A e l ( p ) A_{e}^{l}(\mathbf{p}) Ael(p)是在对齐阶段的图像块匹配误差, C e C_{e} Ce是可以设定的参数,当图像中出现遮挡、运动的物体时, I e \mathcal{I}_{e} Ie就会控制算法关闭这一区域的降噪。另外 I Δ ( p ) = ( 1 + exp ⁡ − ( ∣ L Δ l ( p ) ∣ − m ) ) − 1 \mathcal{I}_{\Delta}(\mathbf{p})=\left(1+\exp ^{-\left(\left|\mathcal{L}_{\Delta}^{l}(\mathbf{p})\right|-m\right)}\right)^{-1} IΔ(p)=(1+exp(LΔl(p)m))1 m ( p ) = 1 + C middle ⋅ ( 1 − exp ⁡ − n l ( p ) ⋅ C noise l ) m(\mathbf{p})=1+C_{\text {middle}} \cdot\left(1-\exp ^{-n^{l}(\mathbf{p}) \cdot C_{\text {noise}}^{l}}\right) m(p)=1+Cmiddle(1expnl(p)Cnoisel)其中 n l ( p ) n^{l}(\mathbf{p}) nl(p)为噪声强度, C n o i s e l C_{\mathrm{noise}}^{l} Cnoisel C middle  C_{\text {middle }} Cmiddle 为可以设定系数,可以发现当 ∣ L Δ l ( p ) ∣ = m ( p ) \left|\mathcal{L}_{\Delta}^{l}(\mathbf{p})\right|=m(\mathbf{p}) LΔl(p)=m(p)是,系数 I Δ ( p ) \mathcal{I}_{\Delta}(\mathbf{p}) IΔ(p)为0.5, I Δ ( p ) \mathcal{I}_{\Delta}(\mathbf{p}) IΔ(p)随噪声强度和像素误差的关系图如下:
    在这里插入图片描述
    可以看到,噪声强度小的时候,像素误差小降噪强度也越小(红色区域),噪声强度大的时候,像素误差小也会有较大的降噪强度(蓝色区域),这个算法从论文的效果看还是很牛逼的,但是自己复现效果怎么样就得看实现了。

    3.《Analysis of Optical Flow Algorithms for Denosing》

    这篇论文应该是2015年的一篇课程总结还是啥,里面有很长的篇幅都是在划水介绍一些基本知识,在后半部分主要是通过实验对比了四种不同的光流算法对降噪效果的影响,并且提出一个结论说先空域降噪后再时域降噪效果会更好,对时域降噪不了解并且时间充裕的同学可以看下这篇论文,这里就不展开了。

    除了这几篇论文外,时域降噪其实是一个大的领域,包括深度学习例如LSTM在这个领域也都有实现,还有基于卡尔曼滤波实现的,但是这些偏学术性会更强,之后有时间再去探究,这篇博客就到这里,有问题欢迎交流~

    此外,这里我写一个各种算法的总结目录图像降噪算法——图像降噪算法总结,对图像降噪算法感兴趣的同学欢迎参考

    展开全文
  • 该文件记载目前各种流行降噪算法的代码下载地址及对应的文档地址,可进行自由下载;算法包括NLM、BM3D、KSVD等传统常规算法,也包括DnCNN、WaveletCNN等新的深度学习算法,并且记录相应测试数据集的下载地址可供自由...
  • 图像降噪算法——图像降噪算法总结

    千次阅读 多人点赞 2020-04-02 17:32:12
    图像传感器与信号处理——图像降噪算法图像传感器与信号处理——图像降噪算法1. 图像噪声建模2. 图像降噪算法 图像传感器与信号处理——图像降噪算法 图像降噪对于SLAM的落地也是非常重要的,这几天我看了几篇和图像...

    图像降噪算法——图像降噪算法总结

    图像降噪算法——图像降噪算法总结

    前面这段时间我看了几篇和图像降噪相关的Review,给我的感觉就是SLAM这一研究领域像是一片汪洋,而图像降噪领域则是另一片汪洋,算法实在太多,刚开始让我接触这个领域会有点蒙圈。

    我主要看了如下三篇Review:
    《Image Denoising Review From Classical to State-of-the-art Approaches,2020》
    《A Brief Review of Image Denoising Algorithms and Beyond,2019》
    《Brief Review of Image Denoising Techniques,2019》
    结合一些大佬的博客,我按照我的理解对图像降噪算法进行了分类,分类的目的是帮助更好掌握各个算法,每篇Review和博客对图像降噪算法的分类都不尽相同,我的也不一定完全准确,下面是按照我的理解对各个算法进行的分类:
    在这里插入图片描述
    在学习图像降噪算法之前,最好先对图像传感器有所了解,如下:

    图像传感器与信号处理——详解CCD与CMOS图像传感器

    图像传感器与信号处理——详解图像传感器噪声

    根据分类,我对其中部分算法进行学习,然后尝试基于OpenCV对算法用C++进行实践,完成了一系列博客,如下:

    图像降噪算法——图像噪声模型

    图像降噪算法——中值滤波/均值滤波/高斯滤波/双边滤波

    图像降噪算法——非局部均值降噪算法

    图像降噪算法——离散傅里叶变换

    图像降噪算法——维纳滤波

    图像降噪算法——小波硬阈值滤波(上)

    图像降噪算法——小波硬阈值滤波(下)

    以上算法C++代码实现都在我的Github中,以下算法为后来补充的算法,代码暂时还没有整理到一起,如下:

    图像降噪算法——混合域:BM3D算法

    图像降噪算法——稀疏表达:K-SVD算法

    图像降噪算法——低秩聚类:WNNM算法

    图像降噪算法——DnCNN / FFDNet / CBDNet / RIDNet / PMRID / SID

    图像降噪算法——Variance Stabilizing Transform / Generalization Anscombe Transform算法

    图像降噪算法——时域降噪算法

    最近两年在时域降噪领域还有一些非常棒的时域降噪算法,例如FastDVD,EDVR等,最近又计划先忙一些其他事情,后面有时间再继续补充。

    展开全文
  • 图像降噪算法——非局部均值降噪算法图像降噪算法——非局部均值降噪算法 图像降噪算法——非局部均值降噪算法

    图像降噪算法——非局部均值降噪算法

    1. 基本原理

    非局部均值降噪算法(Non-Local Means)是空间降噪算法的一种,和中值滤波、高斯滤波这些局部滤波算法不同的是,非局部均值降噪算法是一种全局的算法,思路是利用整幅图像中相似像素的灰度值来代替当前像素的灰度值 u ^ i ( p ) = 1 C ( p ) ∑ q ∈ B ( p , r ) u i ( q ) w ( p , q ) \hat{u}_{i}(p)=\frac{1}{C(p)} \sum_{q \in B(p, r)} u_{i}(q) w(p, q) u^i(p)=C(p)1qB(p,r)ui(q)w(p,q)其中, u i ( q ) u_{i}(q) ui(q)是噪声图像像素 q q q的灰度值; u ^ i ( p ) \hat{u}_{i}(p) u^i(p)是降噪后图像像素 p p p的灰度值; w ( p , q ) w(p, q) w(p,q)是像素 p p p q q q之间的权重; B ( p , r ) B(p, r) B(p,r)为噪声图像中,以像素 p p p为中心,宽为 2 r + 1 2r+1 2r+1的区域, C ( p ) C(p) C(p)为权重归一化系数,计算公式为: C ( p ) = ∑ q ∈ B ( p , r ) w ( p , q ) C(p)=\sum_{q \in B(p, r)} w(p, q) C(p)=qB(p,r)w(p,q)

    公式很好理解,中间比较重要的就是权重如何设计,权重需要描述两个像素之间的相似度,而这个相似度通常是通过这两个像素邻域像素间的欧拉距离来描述: d 2 ( B ( p , f ) , B ( q , f ) ) = 1 3 ( 2 f + 1 ) 2 ∑ i = 1 3 ∑ j ∈ B ( 0 , Ω ) ( u i ( p + j ) − u i ( q + j ) ) 2 d^{2}(B(p, f), B(q, f))=\frac{1}{3(2 f+1)^{2}} \sum_{i=1}^{3} \sum_{j \in B(0, \Omega)}\left(u_{i}(p+j)-u_{i}(q+j)\right)^{2} d2(B(p,f),B(q,f))=3(2f+1)21i=13jB(0,Ω)(ui(p+j)ui(q+j))2其中, 3 3 3次求和是对于彩色图而言的, B ( p , f ) B(p, f) B(p,f)为噪声图像中,以像素 p p p为中心,宽为 2 f + 1 2f+1 2f+1的区域,在这个基础上,添加指数核函数来计算权值: w ( p , q ) = e − max ⁡ ( d 2 − 2 σ 2 , 0 , 0 ) h 2 w(p, q)=e^{-\frac{\max \left(d^{2}-2 \sigma^{2}, 0,0\right)}{h^{2}}} w(p,q)=eh2max(d22σ2,0,0)其中, σ \sigma σ h h h是我们人为设定的参数,以上就完成了非局部均值降噪算法的理论介绍。

    2. C++代码实现

    这里我基于OpenCV完成了两份代码,其中第一份是我根据上面公式自己实现,比较容易理解,但是运行速度较慢。因为太慢了,所以我尝试写了第二份代码。第二份是参考他人的代码基于Mat指针实现的,因为是指针操作,所以运行速度会相对较快。

    第一份代码

    Mat Denoise::NonLocalMeansFilter(const Mat &src, int searchWindowSize, int templateWindowSize, double sigma, double h)
    {
        Mat dst, pad;
        dst = Mat::zeros(src.rows, src.cols, CV_8UC1);
    
        //构建边界
        int padSize = (searchWindowSize+templateWindowSize)/2;
        copyMakeBorder(src, pad, padSize, padSize, padSize, padSize, cv::BORDER_CONSTANT);
    
        int tN = templateWindowSize*templateWindowSize;
        int sN = searchWindowSize*searchWindowSize;
    
        vector<double> gaussian(256*256, 0);
        for(int i = 0; i<256*256; i++)
        {
            double g = exp(-max(i-2.0*sigma*sigma, 0.0))/(h*h);
            gaussian[i] = g;
            if(g<0.001)
                break;
        }
    
        //遍历图像上每一个像素
        for(int i = 0; i<src.rows; i++)
        {
            for(int j = 0; j<src.cols; j++)
            {
                cout<<i<<" "<<j<<endl;
                //遍历搜索区域每一个像素
                int pX = i+searchWindowSize/2;
                int pY = j+searchWindowSize/2;
                vector<vector<double>> weight(searchWindowSize, vector<double>(searchWindowSize, 0));
                double weightSum = 0;
                for(int m = searchWindowSize-1; m>=0; m--)
                {
                    for(int n = searchWindowSize-1; n>=0; n--)
                    {
                        int qX = i+m;
                        int qY = j+n;
                        int w = 0;
                        for(int x = templateWindowSize-1; x>=0; x--)
                        {
                            for(int y = templateWindowSize-1; y>=0; y--)
                            {
                                w += pow(pad.at<uchar>(pX+x, pY+y) - pad.at<uchar>(qX+x, qY+y), 2);
                            }
                        }
                        weight[m][n] = gaussian[(int)(w/tN)];
                        weightSum += weight[m][n];
                    }
                }
                dst.at<uchar>(i,j) = 0;
                double sum = 0;
                for(int m = 0; m<searchWindowSize; m++)
                {
                    for(int n = 0; n<searchWindowSize; n++)
                    {
                       sum += pad.at<uchar>(i+templateWindowSize/2+m, j+templateWindowSize/2+n)*weight[m][n];
                    }
                }
                dst.at<uchar>(i,j) = (uchar)(sum/weightSum);
            }
        }
    
        return dst;
    }
    

    第二份代码

    Mat Denoise::NonLocalMeansFilter2(const Mat &src, int searchWindowSize, int templateWindowSize, double sigma, double h)
    {
        Mat dst, pad;
        dst = Mat::zeros(src.rows, src.cols, CV_8UC1);
    
        //构建边界
        int padSize = (searchWindowSize+templateWindowSize)/2;
        copyMakeBorder(src, pad, padSize, padSize, padSize, padSize, cv::BORDER_CONSTANT);
    
        int tN = templateWindowSize*templateWindowSize;
        int sN = searchWindowSize*searchWindowSize;
        int tR = templateWindowSize/2;
        int sR = searchWindowSize/2;
    
        vector<double> gaussian(256*256, 0);
        for(int i = 0; i<256*256; i++)
        {
            double g = exp(-max(i-2.0*sigma*sigma, 0.0))/(h*h);
            gaussian[i] = g;
            if(g<0.001)
                break;
        }
    
        double* pGaussian = &gaussian[0];
    
        const int searchWindowStep = (int)pad.step - searchWindowSize;
        const int templateWindowStep = (int)pad.step - templateWindowSize;
    
        for(int i = 0; i < src.rows; i++)
        {
            uchar* pDst = dst.ptr(i);
            for(int j = 0; j < src.cols; j++)
            {
                cout<<i<<" "<<j<<endl;
                int *pVariance = new int[sN];
                double *pWeight = new double[sN];
                int cnt = sN-1;
                double weightSum = 0;
    
                uchar* pCenter = pad.data + pad.step * (sR + i) + (sR + j);//搜索区域中心指针
                uchar* pUpLeft = pad.data + pad.step * i + j;//搜索区域左上角指针
                for(int m = searchWindowSize; m>0; m--)
                {
                    uchar* pDownLeft = pUpLeft + pad.step * m;
    
                    for(int n = searchWindowSize; n>0; n--)
                    {
                        uchar* pC = pCenter;
                        uchar* pD = pDownLeft + n;
    
                        int w = 0;
                        for(int k = templateWindowSize; k>0; k--)
                        {
                            for(int l = templateWindowSize; l>0; l--)
                            {
                                w += (*pC - *pD)*(*pC - *pD);
                                pC++;
                                pD++;
                            }
                            pC += templateWindowStep;
                            pD += templateWindowStep;
                        }
                        w = (int)(w/tN);
                        pVariance[cnt--] = w;
                        weightSum += pGaussian[w];
                    }
                }
    
                for(int m = 0; m<sN; m++)
                {
                    pWeight[m] = pGaussian[pVariance[m]]/weightSum;
                }
    
                double tmp = 0.0;
                uchar* pOrigin = pad.data + pad.step * (tR + i) + (tR + j);
                for(int m = searchWindowSize, cnt = 0; m>0; m--)
                {
                    for(int n = searchWindowSize; n>0; n--)
                    {
                        tmp += *(pOrigin++) * pWeight[cnt++];
                    }
                    pOrigin += searchWindowStep;
                }
                *(pDst++) = (uchar)tmp;
    
                delete pWeight;
                delete pVariance;
            }
        }
        return dst;
    }
    

    下面是输出结果
    首先是原图:
    在这里插入图片描述

    添加高斯噪声后:
    在这里插入图片描述
    通过非局部均值降噪算法降噪效果:
    在这里插入图片描述
    可以看出这个效果还是非常感人的

    3. 结论

    1. 可以看到非局部均值降噪算法的效果视觉上是非常可以接受的,但是它的缺点是时间复杂度太高,可以清楚看到程序里面有六个for循环,当我把搜索尺寸设为21,模板尺寸设为7是:
      第一份代码运行时间:135.034秒
      第二份代码运行时间:29.6425秒
      OpenCV库函数运行时间:0.512942秒
      通过对比可以发现,Mat通过at函数操作速度要慢于指针操作,而我写的指针操作的代码要远慢于OpenCV库函数,OpenCV中的库函数应该是采用多线程操作。
    2. 2014年有一篇paper讲的是通过积分图的方式优化NLM,我对其进行的C++代码实现,单线程下速度能提高到7秒左右,同时我也简单读了下OpenCV的原理,同样是使用了空间换时间的思想,不过相对积分图的方式会更加巧妙,值得进一步学习。

    此外,这里我写一个各种算法的总结目录图像降噪算法——图像降噪算法总结,对图像降噪算法感兴趣的同学欢迎参考

    展开全文
  • 语音降噪算法

    2021-03-30 10:37:18
    SNR越低,降噪效果越差 1.LMS自适应滤波器、陷波器降噪...2)当用户使用蓝牙耳机或有线耳机通话时,手机端的双麦克风降噪算法往往又会失效。 3)双麦克风在工业设计上也会造成很多阻碍。两个麦克风会让声学音频路径的设计

    SNR越低,降噪效果越差
    1.LMS自适应滤波器、陷波器降噪
    2.普减法
    3.维纳滤波降噪
    4.双麦克风降噪

    双麦克风,一个放在靠近嘴巴的地方收集人声,一个放在顶端或背部收集环境音,再通过算法将人声从背景音中剥离出来,传送到手机的另一端。
    缺点:
    1)有时用户不再说话时,靠近嘴部的麦克风收集的其实还是环境噪音,对于人声剥离的计算会产生一种断断续续的状况。
    2)当用户使用蓝牙耳机或有线耳机通话时,手机端的双麦克风降噪算法往往又会失效。
    3)双麦克风在工业设计上也会造成很多阻碍。两个麦克风会让声学音频路径的设计更加复杂,在ODM和OEM角度都会增加生产设计成本。
    4)在一些使用场合中,用来收集人声的麦克风不一定会被放在人们的嘴边。例如在录音,或者应用一些App上的对讲机功能时,人习惯将手机放置在桌子上,或者拿在举例嘴略远地方。这时两个麦克风很难接收到不同的声音,让算法起不到作用。
    传统的双麦降噪有一定的局限性:
    1) .非平稳降噪不理想,地铁中的哨声或路边的噪声等非平稳噪声,双麦降噪算法处理效果差;2).鲁棒性差。当用户处于免提模式或手持手机离嘴稍远时,降噪效果不明显;3).这种传统的双麦降噪在硬件设计上有很大的局限性。
    5.AI降噪
    1)中国科技大学语音与语言信息处理国家工程实验室
    深度神经网络+单麦克风实现主动降噪的论文。具体实现方式是,建立含有噪声+人声和纯净人声的数据集,以深度神经网络为架构训练出分离噪声和人声的“语音增强回归”算法。
    在初步试验后,这种算法的结果还不错。从训练成本来看,即使用人工合成的数据,算法结果仍然表现优秀。也就是说算法的应用者不需要面对到现实世界收集数据,可能会侵犯隐私的难题。
    从应用上来说,这一算法的降噪能力并不比双麦克模式差,甚至还能克服双麦克风克服不不了的间断噪声问题,有时候人们在走路或跑动时接电话会形成偶尔出现的间断噪声,以往的双麦克风模式很难捕捉到这种噪声,但语音增强回归算法就能将人声从中剥离开来。
    优点:
    1)更鲁棒的模式,
    2)覆盖更广的噪声场景,能够实时分离人声和环境噪声,在任何噪声环境下都能提取出清晰的人声。
    3)不需要依靠多个麦克风,鲁棒性强,不受声源方向的限制。即使在用户手持通话时,手机离他的嘴很远,通话是在大仰角下进行的,他也可以毫不费力地与对方通话清楚。

    展开全文
  • 基于相空间重构与独立分量分析的局部独立投影降噪算法,黄艳林,李友荣,针对故障分析信号中存在噪声问题,提出一种将相空间重构与独立分量分析相结合的局部独立投影降噪算法。其中相空间重构的目的在于
  • 点击上方“小白学视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达 本文转自:AI算法与图像处理图像降噪,是最简单也是最基础的图像处理逆问题(inverse prob...
  • 降噪是音频图像算法中的必不可少的。 目的肯定是让图片或语音 更加自然平滑,简而言之,美化。 图像算法和音频算法 都有其共通点。 图像是偏向 空间 处理,例如图片中的某个区域。 图像很多时候是以二维数据为主,...
  • 问题与挑战 传统降噪算法面临的挑战如下: 非平稳突发性噪声抑制能力差,比如户外直播场景中突然出现的汽车鸣笛声,传统降噪算法就难以消除干净 传统算法增强后会有很多残留噪声,这些噪声会导致主观听感差,甚至...
  • 基于AK次奇异值分解的高斯噪声焦平面偏振图像传感器的降噪算法
  • 针对图像去噪过程中存在边缘保持与噪声抑制之间的矛盾,提出了一种基于变指数的片相似性扩散图像降噪算法。算法基于变指数的自适应降噪模型,引入片相似性的思想,构造出新的边缘检测算子和扩散系数函数。传统的各项...
  • 【Camera专题】HAL1- 多帧降噪算法的集成(实战1) 前面2篇文章,我们学习了集成算法的基本套路,也自己尝试写一个简单的算法进行集成。 本文将进入实战系列,学习和使用第三方算法公司的算法,集成到系统中。 知识点 ...
  • 图像降噪算法总结

    千次阅读 2019-02-26 14:43:11
    图像降噪算法总结 图像降噪,是最简单也是最基础的图像处理逆问题(inverse problem)。 大多数情况下,图像降噪都是ill-posed的问题。因为通过有噪音的观察,总是无法逆向求得唯一正确的干净图片。就好像让你解一...
  • 图像降噪算法——稀疏表达:K-SVD算法图像降噪算法——稀疏表达:K-SVD算法1. 基本原理2. python代码3. 结论 图像降噪算法——稀疏表达:K-SVD算法 为了完善下自己降噪算法知识版图的完整性,我打算花一个周末的时间...
  • 视频降噪时域滤波算法受运算量的限制较大,容易产生由于匹配块搜索不准确引 起的块效应。 在系统地阐述了视频图像降噪的基本理论与发展现状的基础上,对运动估计 进行了深入学习和探讨,提出了一种基于运动估计的...
  • 降噪算法概述

    千次阅读 2019-03-21 11:01:22
    噪声来源众多,随应用场合不同而特性各异,因此难以找到一种通用的语音增强算法可以适用于各种噪声环境,必须针对不同环境下的噪声采取不同的语音增强策略。因此,要进行语音增强首先要了解语音特性、人耳感知特性和...
  • 调用speex库进行语音降噪的代码,可以直接运行,直接看到降噪效果

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 13,082
精华内容 5,232
关键字:

降噪算法