泊松融合原理浅析

2024-04-21 04:18
文章标签 原理 浅析 融合 泊松

本文主要是介绍泊松融合原理浅析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

图像融合是图像处理领域的一个子领域,主要目的是将不同图像的一部分放在一起,融合得到一张新的图像。结果越自然,说明该融合算法就越好。常见的融合算法有Alpha blending、Laplacian Pyramid blending(拉普拉斯金字塔融合/多频带融合)和Poisson Blending。
在这里插入图片描述

泊松融合(Poisson Blending)是图像处理领域著名的图像融合算法,自从2003年发表以来,有很多基于此算法的应用和改进研究出现。泊松融合无需像Alpha blending一样的精确抠图就可以得到很自然的结果。

数学知识预备

梯度,拉普拉斯,散度:
在这里插入图片描述
拉普拉斯方程,又名调和方程、位势方程,是一种偏微分方程。因为由法国数学家皮埃尔-西蒙·拉普拉斯首先提出而得名。求解拉普拉斯方程是电磁学、天文学、热力学和流体力学等领域经常遇到的一类重要的数学问题,因为这种方程以势函数的形式描写电场、引力场和流场等物理对象(一般统称为“保守场”或“有势场”)的性质。

二维拉普拉斯方程如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
拉普拉斯方程是泊松方程的一个特例。

论文内容解析

泊松融合的核心思想不是让需要融合的两张图像直接叠加,而是让目标图像(dst)在融合部分根据源图像(src)的引导场(实际是梯度场 gradient field )“生长”出新的图像。

也就是说,只需要提供源图像的梯度场,让目标图像根据自身特点,按照源图像对应的梯度场生成融合部分。由于目标图像是按照自身特点出发生成融合区域,所以融合结果会显得更加自然。

在这里插入图片描述
在论文中,作者将这种梯度场引导插值操作统一称为“泊松编辑(Poisson Image Editing)”。根据梯度场的处理不同,泊松融合可以分为NORMAL CLONE、MIXED CLONE、MONOCHROME TRANSFER三大类。泊松编辑除了泊松融合外还有Texture flattening、Local illumination changes、Local color changes等应用场景。

在示意图图一中, S S S是二维实数集 R 2 \Bbb{R}^2 R2的闭合子集, Ω \Omega Ω S S S的边界为 ∂ Ω \partial\Omega Ω闭合子集。 f ∗ f^* f是集合 S − Ω S-\Omega SΩ 部分的函数(如果是图像的话就是指所有像素的像素值), f f f是集合 Ω \Omega Ω 的函数(也就是需要靠解泊松方程来求的函数)。 v \bold v v是集合 Ω \Omega Ω的向量场(构建泊松方程所需)。

最简单的插值结果是如下最小化问题的解:
在这里插入图片描述
在这里插入图片描述
该问题的解必须满足其Euler-Lagrange等式:
在这里插入图片描述
在这里插入图片描述
等式(2)是带有狄利克雷边界条件的拉普拉斯方程。

在图像融合中,这种简单的插值方法会产生不连续、模糊的插值效果。这时候可以通过引入集合 Ω \Omega Ω的向量场 v \bold v v来改善。以此方式构建的最小化问题如下:
在这里插入图片描述
该问题的解是如下带有狄利克雷边界条件的泊松方程。
在这里插入图片描述
在这里插入图片描述
也就是说,拉普拉斯方程是泊松方程的一种特例(divv=0)。

需要注意的是上述过程的求解是针对图像单个通道的,如果是RGB通道则需要构建三个泊松方程求解。

对于图像而言,像素点是离散点,因此上述连续空间的偏微分方程可以改写为离散空间的偏微分方程:
在这里插入图片描述
其中,p是S中的像素点, N p N_p Np是像素p的四邻域,<p, q>是像素对。此时 Ω \Omega Ω的边界变为 ∂ Ω = { p ∈ S ∖ Ω : N p ∩ Ω ≠ ∅ } \partial\Omega=\{p\in S \setminus \Omega:N_p\cap\Omega \not = \emptyset\} Ω={pSΩ:NpΩ=} f p f_p fp f f f在p点的值。
在这里插入图片描述

等式(6)的解满足如下联立线性方程:
在这里插入图片描述
当方程中的像素p的四邻域不包含边界点( ∂ Ω \partial\Omega Ω)时:
在这里插入图片描述
在这里插入图片描述

关于泊松方程的求解,原论文中有如下描述:
在这里插入图片描述
方程(7)形式构成一个经典的、稀疏带状、对称、正定系统。可以通过带successive overrelaxation(逐次超松弛)的Gauss-Seidel iteration(高斯-赛德尔迭代)或者V-cycle multigrid方法求解。
在这里插入图片描述
根据泊松方程构建形式的不同可以选择上述两种不同的方法进行求解。

另外梯度场V不仅可以是源图像的梯度场,还可以是其他。对引导场进行设计可以将泊松编辑应用到各种场景中:

NORMAL CLONE
在这里插入图片描述

MIXED CLONE
在这里插入图片描述

MONOCHROME TRANSFER
在这里插入图片描述Texture flattening
在这里插入图片描述

Local illumination changes
在这里插入图片描述
Local color changes
在这里插入图片描述

方法原理

泊松融合的目的是将源图像的一部分无缝融合到目标图像上。其本质是在保持目标图在融合边界的像素的同时以源图像的该部分的梯度场作为指导来生成融合区域内的像素。整体原则是保持融合区域内的生成像素的梯度场与源图像融合部分的像素的梯度场尽可能一致,反映到方程求解中则是梯度差异尽可能小。也就是让生成区域的拉普拉斯结果和源图像的拉普拉斯结果一致,且生成区域边界的的值和目标图像在融合区域的边界值一致。
在这里插入图片描述
以一维场景为例说明,如下图,需要将左侧直方图中红色的部分融合到右侧直方图中的空缺处,红色柱子上方的数值是其梯度。
在这里插入图片描述
根据方程:
在这里插入图片描述

可以列出:
在这里插入图片描述
f 1 f_1 f1 f 6 f_6 f6的值代入并展开:
在这里插入图片描述
对所有min(*)进行求和:
在这里插入图片描述
求偏导:
在这里插入图片描述
写成矩阵形式:
在这里插入图片描述
在这里插入图片描述

矩阵求解:
在这里插入图片描述

融合结果如下:
在这里插入图片描述
对于二维图像而言:
在这里插入图片描述
X方向和Y方向的梯度可以求得:
在这里插入图片描述
可以通过得到的梯度场和边界像素重建回原始图像:
在这里插入图片描述
将图像G融合到图像I上:
在这里插入图片描述
改写成矩阵形式:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
对于 N ∗ N N*N NN大小的图像,矩阵A的大小 N 2 ∗ N 2 N^2*N^2 N2N2,存储A是不现实的,由于A在形式上是稀疏、对称、正定的,可以选用如下方法进行求解:
在这里插入图片描述
维基百科中列出的解法:
在这里插入图片描述

OpenCV实现

OpenCV已经有泊松融合(编辑)的实现代码,接口如下:
在这里插入图片描述
最基本的泊松融合函数如下:
在这里插入图片描述
OpenCV GitHub源码:
在这里插入图片描述
关于泊松融合OpenCV实现代码将在后续博客中进行详解,值得一提的是OpenCV中的泊松方程求解采用了离散傅里叶变换方法,有兴趣可以详读该部分源码。

代码示例

import cv2src_bgr = cv2.imread('xingye.jpg', 1)
dst_bgr = cv2.imread('xiangrikui.jpg', 1)resize = (70, 120)
src_bgr_resize = cv2.resize(src_bgr, (resize[1], resize[0]))
mask = np.ones((src_bgr_resize.shape[0], src_bgr_resize.shape[1]))mask_inner = mask[1:-1, 1:-1]
mask = cv2.copyMakeBorder(mask_inner, 1, 1, 1, 1, cv2.BORDER_ISOLATED | cv2.BORDER_CONSTANT, value=0)mask = mask*255p = (290, 610)out_img = cv2.seamlessClone(src_bgr_resize.astype(np.uint8), dst_bgr.astype(np.uint8), mask.astype(np.uint8), p, cv2.NORMAL_CLONE)cv2.imwrite('out_img.png', out_img)

xingye.jpg:
在这里插入图片描述
xiangrikui.jpg:
在这里插入图片描述
out_img.png:
在这里插入图片描述

在这里插入图片描述

参考资料

[1] OpenCV Docs - Seamless Cloning
[2] OpenCV GitHub - opencv/modules/photo/src/seamless_cloning.cpp
[3] OpenCV GitHub - opencv/modules/photo/src/seamless_cloning_impl.cpp
[4] csdn - 图像处理(十二)图像融合(1)Seamless cloning泊松克隆-Siggraph 2004
[5] 知乎 - 12. 泊松图像编辑
[6] 图像融合之泊松融合(Possion Matting) - 一度逍遥 - 博客园
[7] 盲解卷积和泊松图像融合 - 哔哩哔哩
[8] OpenCV Docs - Image Filtering
[9] OpenCV Docs - cv::dft
[10] OpenCV Docs - cv::cuda::createLaplacianFilter
[11] OpenCV Docs - cv::cuda::DFT
[12] OpenCV GitHub - opencv_contrib/modules/cudaarithm/src/arithm.cpp
[13] Poisson equation, solving with DFT - Algowiki
[14] Numerical Analysis of Boundary-Value Problems (AMATH 585)
[15] 矩阵计算
[16] Opencv中使用cuda进行 dft 与 idft滤波运算 | YangYouji’s WebSite
[17] OpenCV Docs - cv::filter2D
[18] OpenCV Docs - Discrete Fourier Transform
[19] 快速傅里叶变换 - 维基百科,自由的百科全书
[20] opencv之Mat数据类型 - feifanren - 博客园
[21] python - OpenCV cv2.seamlessClone中的错误 - 堆栈内存溢出
[22] python - bug on bounds in OpenCV cv2.seamlessClone - Stack Overflow
[23] seamlessClone bug · Issue #15294 · opencv/opencv
[24] epock / epock / issues / #48 - terminate called after throwing an instance of ‘std::length_error’ — Bitbucket
[25] opencv/pyopencv_cuda.hpp at master · opencv/opencv
[26] 计算机视觉:泊松融合
[27] 松弛法求解给定边界条件的泊松方程
[28] 泊松融合笔记
[29] FFT解泊松方程
[30] 拉普拉斯方程 - 维基百科,自由的百科全书
[31] 泊松方程 - 维基百科,自由的百科全书
[32] Discrete Poisson equation - Wikipedia
[33] OpenCV: samples/cpp/tutorial_code/photo/seamless_cloning/cloning_demo.cpp
[34] 图像融合之多波段融合(Multiband Blending)/拉普拉斯金字塔融合(Laplacian Pyramid Blending)
[35] An Intuitive Explanation of using Poisson Blending for Seamless Copy-and-Paste of Images

这篇关于泊松融合原理浅析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/922137

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Redis中Set结构使用过程与原理说明

《Redis中Set结构使用过程与原理说明》本文解析了RedisSet数据结构,涵盖其基本操作(如添加、查找)、集合运算(交并差)、底层实现(intset与hashtable自动切换机制)、典型应用场... 目录开篇:从购物车到Redis Set一、Redis Set的基本操作1.1 编程常用命令1.2 集

Redis中的有序集合zset从使用到原理分析

《Redis中的有序集合zset从使用到原理分析》Redis有序集合(zset)是字符串与分值的有序映射,通过跳跃表和哈希表结合实现高效有序性管理,适用于排行榜、延迟队列等场景,其时间复杂度低,内存占... 目录开篇:排行榜背后的秘密一、zset的基本使用1.1 常用命令1.2 Java客户端示例二、zse

Redis中的AOF原理及分析

《Redis中的AOF原理及分析》Redis的AOF通过记录所有写操作命令实现持久化,支持always/everysec/no三种同步策略,重写机制优化文件体积,与RDB结合可平衡数据安全与恢复效率... 目录开篇:从日记本到AOF一、AOF的基本执行流程1. 命令执行与记录2. AOF重写机制二、AOF的

java程序远程debug原理与配置全过程

《java程序远程debug原理与配置全过程》文章介绍了Java远程调试的JPDA体系,包含JVMTI监控JVM、JDWP传输调试命令、JDI提供调试接口,通过-Xdebug、-Xrunjdwp参数配... 目录背景组成模块间联系IBM对三个模块的详细介绍编程使用总结背景日常工作中,每个程序员都会遇到bu

Python中isinstance()函数原理解释及详细用法示例

《Python中isinstance()函数原理解释及详细用法示例》isinstance()是Python内置的一个非常有用的函数,用于检查一个对象是否属于指定的类型或类型元组中的某一个类型,它是Py... 目录python中isinstance()函数原理解释及详细用法指南一、isinstance()函数

java 恺撒加密/解密实现原理(附带源码)

《java恺撒加密/解密实现原理(附带源码)》本文介绍Java实现恺撒加密与解密,通过固定位移量对字母进行循环替换,保留大小写及非字母字符,由于其实现简单、易于理解,恺撒加密常被用作学习加密算法的入... 目录Java 恺撒加密/解密实现1. 项目背景与介绍2. 相关知识2.1 恺撒加密算法原理2.2 Ja