常见图像融合算法(图像泊松融合)
一、背景介绍
上一篇已经讲过alpha和金字塔融合基本实现,这里主要是继续对图像常用的泊松融合算法和他的一些性能版本实现的基本讲解。
二、原始版本
1、基本原理
图像泊松融合也是普遍使用的常规算法,很多小伙伴已经分享过它的基本原理和实现了,对细节原理感兴趣的小伙伴可以参考:【手撕算法】图像融合之泊松融合:原理讲解及C++代码实现-腾讯云开发者社区-腾讯云
2、实现流程
(1)、拿到前景和背景图像。
(2)、设置好前景需要回帖的背景区域位置。
(3)、填充求解泊松的A矩阵。
(4)、计算求解泊松的B矩阵:
a、拉普拉斯算子直接计算前景图像散度,得到初始B矩阵。
b、根据边界条件填充B矩阵边界像素(本文案例代码使用的是Dirichlet 边界):
Neumann 边界:使用前景边缘散度和背景图像在这些位置的散度差值。
Dirichlet 边界:使用前景边缘散度和背景图像在这些位置的原始像素差值。
(5)、使用最小二乘法,求解Ax=B,由于A,B已知,因此可以直接得到x,也就是我们期望的泊松融合结果。
3、效果演示
从左往右分别为:前景,背景和融合结果(素材和原始代码来源自:【手撕算法】图像融合之泊松融合:原理讲解及C++代码实现-腾讯云开发者社区-腾讯云):
4、代码实现
简单整理了下的原始版本:
https://github.com/yulinghan/ImageQualityEnhancement/tree/master/image_fusion/poisson_origithub.com/yulinghan/ImageQualityEnhancement/tree/master/image_fusion/poisson_ori
三、fft加速版本
1、基本原理
由于原始的泊松性能和内存开销实在太大,因此在原始版本基础上,很多大佬做了各种优化算法,最常见的比如有opencv默认使用的fft加速版本,本篇的代码也是从opencv源码从扣出来的。
它的加速原理也有很多小伙伴介绍过了,我这里也不做太多讲解了,感兴趣的小伙伴,可以参考:泊松融合进阶——DFT求解二维泊松方程 等资料。
2、实现流程
(1)、拿到前景和背景图像。
(2)、设置好前景需要回帖的背景区域位置。
(3)、拉普拉斯算子直接计算前景图像散度,得到前景散度图L1。
(4)、对L1图像填充边界条件,opencv里面默认使用的是Neumann 边界。
(5)、对填充后的L1图像,使用离散傅里叶变换求解,得到泊松融合后结果图像。
3、效果演示
实际效果和原始版本差不多的,这里就不贴图了。
性能数据上:原始版本上,处理一张80x40x3的图,花了42秒左右。
fft加速版本上,处理一张512x512x3的图,花了大概250ms左右。
4、代码实现
从opencv库里扣出来实现代码,并基本整理后地址:
https://github.com/yulinghan/ImageQualityEnhancement/tree/master/image_fusion/poisson_fft