BM3D 算法原理详细解析 按过程步骤讲解(附C++实现代码)[通俗易懂]

BM3D 算法原理详细解析 按过程步骤讲解(附C++实现代码)[通俗易懂]BM3D是2007年提出的算法了,至今已经有一些年头了,但是仍然不妨碍它基本上还是最强的去噪算法。在初步了解了BM3D的算法后,会发现,BM3D有种堆叠怪的嫌疑。有很多不同的算法的影子在里面,比如Non-LocalMeans、Waveletshrinkage等。我感觉思想更像是暴力出奇迹吧。但是架不住效果好。就类似现在的神经网络,一层不行我就来两层。但是相比简单的堆叠,BM3D还是比其他的算法的细节保留上要好一些。好了,不废话了,下面直接来看BM3D的算法原理吧。BM3D算法原理:

大家好,又见面了,我是你们的朋友全栈君。

BM3D是2007年提出的算法了,至今已经有一些年头了,但是仍然不妨碍它基本上还是最强的去噪算法。

在初步了解了BM3D的算法后,会发现,BM3D有种堆叠怪的嫌疑。有很多不同的算法的影子在里面,比如Non-Local Means、Wavelet shrinkage等。

我感觉思想更像是暴力出奇迹吧。但是架不住效果好。就类似现在的神经网络,一层不行我就来两层。

但是相比简单的堆叠,BM3D还是比其他的算法的细节保留上要好一些。

(完整代码Github地址在最后)

好了,不废话了,下面直接来看BM3D的算法原理吧。

BM3D算法原理:

BM3D 算法原理详细解析 按过程步骤讲解(附C++实现代码)[通俗易懂]

                                                              (原理图)

BM3D算法主要分两步(按collaborative filtering划分)

Step1:

S1、 在collaborative filtering阶段使用hard threshold

        S1.1—grouping:在image中寻找相似块,使用hard threshold定义相似性,进而stack into不同的block;

                   ①与Non-Local Means相似,先寻找出所有的block,并且做初步的2D变换。【1】方便后面的Grouping.

                   ②在SearchWindows中,Grouping所有的Block。(由于边界原因,不同的Group,Group的大小不同)。

                                     BM3D 算法原理详细解析 按过程步骤讲解(附C++实现代码)[通俗易懂]

                        (Grouping 过程与Non-Local Means相似,可以设置Stride大小。代码中有另外的加速实现)

                   ③计算block之间的L2 distance,并根据distance的大小顺序进行排列。

BM3D 算法原理详细解析 按过程步骤讲解(附C++实现代码)[通俗易懂]

        S1.2— collaborative filtering:对每一个相似grouped block做3D线性变换,shrinkage of the transform spectrum,最后在逆变换得到basic estimate block;

                   ①在每一个Group中,我们都有了相似的Block集合。然后进行3D的线性变换。但是由于3D线性变换较为复杂。一般使用一次2D的变换以及第三维度的1D变换进行代替。我这里使用了2D的DCT变换,以及1D的Haar变换。

                   ②在前面S1.1.①中,我们已经对所有的block进行了2D的DCT变换。所以我们直接对每一个Group进行第三维的1D变换即可。到此,完成了一次完整的3D变换。

                   ③Hard Threshold阈值化处理。对3D变换后的Group进行一次硬阈值的控制,将不符合条件的3D转换值直接变为0。

                   ④对Threshold后的Group进行像素值为0的统计,根据0的个数,计算出权重weight。

                   ⑤将所有的Group进行3D逆转换。当然,这里同样使用一次2D逆转换和一次1D逆转换进行代替。我当然是使用了1D的Haar逆转换和2D的IDCT转换。

                   ⑥然后将Group中的所有图片按照权重值aggregate到图像中。

                   ⑦得到Step1的结果图像 image_basic

        S1.3—aggregation:因为前面每一个patch在3D block逆变换后对应的多个,经验的做法是直接平均所有的块,但更建议根据得到的patch质量,赋予不同的权值加权平均。不难看出aggregation是一个特殊的平均过程,类似于NNLM方法,利用图片的冗余性恢复含噪图片。  

                   ①这一步挺简单的,就是根据前面S1.2.④计算出的权重和一个自定义的kaiser Windows进行叠加即可。如果你想简单一点,直接平均也可,但是效果肯定没那么好。

S2、步骤和S1类似,如下图,不同之处有两点[2]:

        S2.1— grouping  

                   ①保留 Step1 中的噪声图像Group   —  ImageNoiseGroup

                   ②将Step1的结果 image_basic进行grouping   —  ImageBasicGroup

        S2.2— collaborative filtering 

                   ①与Step 1不同,Step 2不适用Hard Threshold,而是采用Wiener Filter。我个人认为这一步的目的是利用维纳滤波的特性,在第一步降噪后的图像的基础上,结合原始图像,恢复图像的一些细节信息。

                       将ImageNoiseGroup和ImageBasicGroup进行一一对应的维纳滤波,从而恢复一定的图像细节

        S2.3—aggregation

                   ①还是一样,结合Kaiser Window进行aggregate。

 

以上即为BM3D的算法原理。老实说,一一按步骤实现的BM3D的算法,处理速度很慢。比如256*256大小的单通道图像处理时间就高达60s

但是我们可以加上很多别的工程上的处理。例如,积分图、多线程、GPU计算等。

实验结果:

BM3D 算法原理详细解析 按过程步骤讲解(附C++实现代码)[通俗易懂]

      (Gaussian noise Image)                     (Step 1 basic Image)                   (Step 2 Denoise Image)

         在实验中发现S2会恢复出更多的图像细节部分,提高去噪性能。BM3D 算法原理详细解析 按过程步骤讲解(附C++实现代码)[通俗易懂]

 

GitHub地址:点我获取完整代码呀~

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/140877.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号