zl程序教程

您现在的位置是:首页 >  后端

当前栏目

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

C++算法原理代码 实现 解析 详细 通俗易懂
2023-06-13 09:11:47 时间

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

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

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

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

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

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

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

BM3D算法原理:

(原理图)

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的大小不同)。

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

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

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计算等。

实验结果:

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

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

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

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