热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python的opencv操作记录(十)——图像融合

文章目录前言opencv中的一个方法泊松融合图像梯度图像散度融合图像散度通过散度场进行图像重建泊松融合的一般逻辑前言最近碰到一个项目上的难题,是要从电动显微镜对焦的




文章目录


  • 前言
  • opencv中的一个方法
  • 泊松融合
    • 图像梯度
    • 图像散度
    • 融合图像散度
    • 通过散度场进行图像重建

  • 泊松融合的一般逻辑



前言

最近碰到一个项目上的难题,是要从电动显微镜对焦的多张图像进行融合。因为,显微镜物镜的景深范围较小,可能在同一视野中有多个需要拍摄的物体位于不同的景深范围内,所以想通过图像的融合,将不同景深上的多张图像进行融合,从而把这些物体都在同一张图像中对用户进行展示。


opencv中的一个方法

在opencv中,提供了一个图像融合函数seamlessClone,可以直接进行图像融合。

dst = cv2.imread("/Users/zoulei/files/personal/images/bg.jpg")
obj = cv2.imread("/Users/zoulei/files/personal/images/fore.jpg")
# Create an all white mask
mask = 255 * np.ones(obj.shape, obj.dtype)
# The location of the center of the src in the dst
width, height, channels = dst.shape
center = (int(height / 2), int(width / 2))
# Seamlessly clone src into dst and put the results in output
normal_clone = cv2.seamlessClone(obj, dst, mask, center, cv2.NORMAL_CLONE)
mixed_clone = cv2.seamlessClone(obj, dst, mask, center, cv2.MIXED_CLONE)
cv2.imshow("origin image", dst)
cv2.imshow("fution image normal", normal_clone)
cv2.imshow("fution image mixed", mixed_clone)
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述

opencv这块的原理应该是基于一个牛逼的图像融合算法:泊松融合,出自于论文[Poisson Image Editing-2003]。于是去了解了一下这个厉害的算法。


泊松融合

泊松融合大概的逻辑是:


  • 将两幅图像都计算散度场,然后将两幅图像的散度场通过掩码进行相加
  • 通过计算泊松方程重建图像。

我自己的理解是求散度之后更好的得到图像更深层的信息,在更深的层次上对图像进行信息融合,然后再重建,比直接了当的把图贴上去效果要好得多。

当然,论文是比较严谨和难懂的,我这里只是大概的记录下过程,以便于理解。


图像梯度

图像梯度的概念在我之前计算清晰度的文章中已经描述过了:
https://blog.csdn.net/pcgamer/article/details/127942102?spm=1001.2014.3001.5502
就不再赘述了。


图像散度

图像的散度的定义就是对图像进行二阶求导,实际上就是拉普拉斯算子:









2



f


=








2



f








2



x




+








2



y








2



x





\nabla^2f=\frac{\partial^2 f}{\partial^2 x} + \frac{\partial^2 y}{\partial^2 x}


2f=2x2f+2x2y

因为图像是离散的数据,所以这个偏导(x方向上)的在离散数据上的定义就是:











2



f








2



x




=


f


(


x


+


1


,


y


)


+


f


(


x





1


,


y


)





2


f


(


x


,


y


)



\frac{\partial^2 f}{\partial^2 x} = f(x+1, y) + f(x-1, y) - 2f(x,y)


2x2f=f(x+1,y)+f(x1,y)2f(x,y)

(x,y)表示图像中的某一个像素值

同样的,在y方向的偏导就是:











2



f








2



y




=


f


(


x


,


y


+


1


)


+


f


(


x


,


y





1


)





2


f


(


x


,


y


)



\frac{\partial^2 f}{\partial^2 y} = f(x, y+1) + f(x, y-1) - 2f(x,y)


2y2f=f(x,y+1)+f(x,y1)2f(x,y)

根据第一个公式,两者相加就是









2



f


=








2



f








2



x




=


f


(


x


+


1


,


y


)


+


f


(


x





1


,


y


)


+


f


(


x


,


y


+


1


)


+


f


(


x


,


y





1


)





4


f


(


x


,


y


)



\nabla^2f=\frac{\partial^2 f}{\partial^2 x} = f(x+1, y) + f(x-1, y) + f(x, y+1) + f(x, y-1) - 4f(x,y)


2f=2x2f=f(x+1,y)+f(x1,y)+f(x,y+1)+f(x,y1)4f(x,y)

从图像意义上来看,对某一个图像数据进行二阶求导就是等于这个像素的上下左右像素值减去自己像素值的四倍。
在图像中就可以使用一个掩膜来进行计算:





[






0






1






0








1










4







1








0






1






0






]



\begin{bmatrix}0 & 1 & 0 \\ 1 & -4 & 1 \\ 0 & 1 & 0\end{bmatrix}


010141010

这个掩膜就是在图像领域的拉普拉斯算子。

计算图像的散度就可以直接将拉普拉斯算子作用于图像上进行计算。
我个人理解这个拉普拉斯可以提取图像中的边缘信息,因为边缘信息的梯度较小,如果一个像素点旁边的像素值都是相同的(也就是没有变化),这个算子计算得出的结果就是0。


融合图像散度

在那边论文描述的融合过程中,应该是把两幅图像分别求梯度场(一阶导数),然后把两幅图像的梯度场相加,然后再对融合梯度场进行一次求导,就是二次梯度场(散度),这就得到了融合图像的散度场。


通过散度场进行图像重建

对论文中的公式看的不是太明白,大概的意思是:
根据拉普拉斯算子的定义,图像进行拉普拉斯算子的卷积运算后就可以得到散度场。

那么,反过来,得到了散度场是否就可以得到原图像呢?答案是肯定的。

大致的思路如下:


  • 假设有这么一副图像:





    [







    x


    1








    x


    2








    x


    3










    x


    4








    x


    5








    x


    6










    x


    7








    x


    8








    x


    9







    ]



    \begin{bmatrix} x_1 & x_2 & x_3 \\ x_4 & x_5 & x_6 \\ x_7 & x_8 & x_9\end{bmatrix}


    x1x4x7x2x5x8x3x6x9

  • 这幅图像对应的散度场:




    V


    (


    5


    )


    =



    x


    2



    +



    x


    4



    +



    x


    6



    +



    x


    8






    4



    x


    5




    V(5) = x_2 + x_4 + x_6 + x_8 - 4x_5


    V(5)=x2+x4+x6+x84x5

  • 总共有9个未知数,现在有了一个方程,如果还有8个方程的话,那么每个未知数就会有一个固定的解了。

  • 关键的点来了:泊松融合的目的是将源图像的一部分无缝融合到目标图像上。其本质是在保持目标图在融合边界的像素的同时以源图像的该部分的梯度场作为指导来生成融合区域内的像素。整体原则是保持融合区域内的生成像素的梯度场与源图像融合部分的像素的梯度场尽可能一致,反映到方程求解中则是梯度差异尽可能小。也就是让生成区域的拉普拉斯结果和源图像的拉普拉斯结果一致,且生成区域边界的的值和目标图像在融合区域的边界值一致。

  • 上面这句话最后说的边界值需要一致,也就是说融合图像的边界值可以和目标图像一致,也就是说上面的9个未知量(不管这个是融合的还是原图像)中,8个是边界,边界像素可以和目标图像一致,也就是已知量,加上这8个方程,联合散度场的计算公式,就可以重建出原始的图像了。


泊松融合的一般逻辑

综上所述,我理解泊松融合就是下面的逻辑:


  1. 计算需要被融合的图像的梯度场
  2. 通过掩码得到目标图像上的ROI区域,计算的到这个ROI的梯度场。
  3. 把第一步和第二步的梯度场相加
  4. 对第三步的梯度场再次求导,得到融合图像的二阶导,也就是散度场
  5. 再对这个散度场进行图像重建,得到融合图像。

在opencv中的seamlessClone函数中,有三个flag方式:


  • NORMAL_CLONE
  • MIXED_CLONE
  • MONOCHROME_TRANSFER

我还没去仔细看opencv的源码,根据我自己的实验,我个人感觉这三个参数主要在于上面的第三步的区别,可能是对两遍的梯度场做了一些权重的设置,看是以哪个梯度场为主来进行图像的生成。


  • NORMAL_CLONE,前需要融合的前景图像为主,边缘基本都保留了
  • MIXED_CLONE,两者的特性都保留
  • MONOCHROME_TRANSFER,保留前景的轮廓,把背景的风格给融合进去。上面没有这样的图像,这里补充一张:

在这里插入图片描述







推荐阅读
  • FIN7后门工具伪装成白帽工具进行传播
    fin7,后门,工具,伪装,成,白, ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 本文介绍了响应式页面的概念和实现方式,包括针对不同终端制作特定页面和制作一个页面适应不同终端的显示。分析了两种实现方式的优缺点,提出了选择方案的建议。同时,对于响应式页面的需求和背景进行了讨论,解释了为什么需要响应式页面。 ... [详细]
  • 2016 linux发行版排行_灵越7590 安装 linux (manjarognome)
    RT之前做了一次灵越7590黑苹果炒作业的文章,希望能够分享给更多不想折腾的人。kawauso:教你如何给灵越7590黑苹果抄作业​zhuanlan.z ... [详细]
  • Android日历提醒软件开源项目分享及使用教程
    本文介绍了一款名为Android日历提醒软件的开源项目,作者分享了该项目的代码和使用教程,并提供了GitHub项目地址。文章详细介绍了该软件的主界面风格、日程信息的分类查看功能,以及添加日程提醒和查看详情的界面。同时,作者还提醒了读者在使用过程中可能遇到的Android6.0权限问题,并提供了解决方法。 ... [详细]
  • 本文介绍了贝叶斯垃圾邮件分类的机器学习代码,代码来源于https://www.cnblogs.com/huangyc/p/10327209.html,并对代码进行了简介。朴素贝叶斯分类器训练函数包括求p(Ci)和基于词汇表的p(w|Ci)。 ... [详细]
  • Python中的PyInputPlus模块原文:https ... [详细]
  • 由于同源策略的限制,满足同源的脚本才可以获取资源。虽然这样有助于保障网络安全,但另一方面也限制了资源的使用。那么如何实现跨域呢,以下是实现跨域的一些方法。 ... [详细]
  • 移动传感器扫描覆盖摘要:关于传感器网络中的地址覆盖问题,已经做过很多尝试。他们通常归为两类,全覆盖和栅栏覆盖,统称为静态覆盖 ... [详细]
  • 阿里Treebased Deep Match(TDM) 学习笔记及技术发展回顾
    本文介绍了阿里Treebased Deep Match(TDM)的学习笔记,同时回顾了工业界技术发展的几代演进。从基于统计的启发式规则方法到基于内积模型的向量检索方法,再到引入复杂深度学习模型的下一代匹配技术。文章详细解释了基于统计的启发式规则方法和基于内积模型的向量检索方法的原理和应用,并介绍了TDM的背景和优势。最后,文章提到了向量距离和基于向量聚类的索引结构对于加速匹配效率的作用。本文对于理解TDM的学习过程和了解匹配技术的发展具有重要意义。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
author-avatar
夫功的美丽家园
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有