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

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

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

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

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

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

BM3D算法原理:

BM3D去噪python bm3d去噪算法原理及代码_3D

                                                              (原理图)

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去噪python bm3d去噪算法原理及代码_3D_02

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

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

BM3D去噪python bm3d去噪算法原理及代码_BM3D去噪python_03

        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去噪python bm3d去噪算法原理及代码_Group_04

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

         在实验中发现S2会恢复出更多的图像细节部分,提高去噪性能。

BM3D去噪python bm3d去噪算法原理及代码_线性变换_05

 

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