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

图像金字塔实现图像融合(基于opencvpython)

图像金字塔介绍图像金字塔是多尺度表达的一种,是一种以多分辨率来解释图像的有效但概念简单的结构。。一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐渐降低并且来源于同

图像金字塔介绍


  • 图像金字塔是多尺度表达的一种,是一种以多分辨率来解释图像的有效但概念简单的结构。。一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐渐降低并且来源于同一张原始图像的集合。通过梯次向下采样获得,直到某个终止条件才停止采样。
  • 图像金字塔说白了就是披着金字塔外衣的图像缩放。一般有高斯图像金字塔、拉普拉斯图像金字塔。

两种金字塔介绍


高斯金字塔(低通)

高斯金字塔:用于下采样。高斯金字塔是最基本的图像塔。
原理:首先将原图像作为最底层图像G0(高斯金字塔的第0层),利用高斯核(5*5)对其进行卷积(高斯平滑),然后对卷积后的图像进行下采样(去除偶数行和列)得到上一层图像G1,将此图像作为输入,重复卷积和下采样操作得到更上一层图像,反复迭代多次,形成一个金字塔形的图像数据结构,即高斯金字塔

由于上采样和下采样是非线性处理,是不可逆的有损处理,因此下采样后的图像想要还原回原来的尺寸的话会丢失很多信息,使图片变模糊。
                在这里插入图片描述
上图就是使用高斯金字塔之后的结果。

拉普拉斯金字塔(带通金字塔)

拉普拉斯金字塔:用于重建图像,也就是预测残差,对图像进行最大程度的还原
一幅小图像重建为一幅大图原理:用高斯金字塔的每一层图像减去其上一层图像上采样并高斯卷积之后的预测图像,得到一系列的差值图像即为 LP 分解图像。

拉普拉斯金字塔实际上是通过计算图片先下采样再上采样后的结果和原图片的残差来保存缺失信息的,公式为:L(i)=G(i)−PyrUp(G(i+1))L(i) = G(i) - PyrUp(G(i + 1))L(i)=G(i)PyrUp(G(i+1))
也就是说,拉普拉斯金字塔实际上是由上面的残差图片组成的金字塔,它为还原图片做准备
求得每个图像的拉普拉斯金字塔后需要对相应层次的图像进行融合,最终还原图像。
拉普拉斯金字塔可以精确还原图片信息。
还原图像的过程就是重构的过程。在这里插入图片描述
上图能够比较好的理解拉普拉斯金字塔的计算过程。

图像金字塔应用

图像金字塔非常重要的一个应用就是实现图像分割。图像分割的话,先要建立一个图像金字塔,然后在Gi和Gi+1的像素直接依照对应的关系,建立起”父与子“关系。而快速初始分割可以先在金字塔高层的低分辨率图像上完成,然后逐层对分割加以优化。

实例1 高斯金字塔和拉普拉斯金字塔显示:

代码:

import cv2 as cv
#高斯金字塔
def pyramid_demo(image):level = 3 #设置金字塔的层数为3temp = image.copy() #拷贝图像pyramid_images = [] #建立一个空列表for i in range(level):dst = cv.pyrDown(temp) #先对图像进行高斯平滑,然后再进行降采样(将图像尺寸行和列方向缩减一半)pyramid_images.append(dst) #在列表末尾添加新的对象cv.imshow("pyramid"+str(i+1), dst)temp = dst.copy()return pyramid_images
#拉普拉斯金字塔
def lapalian_demo(image):pyramid_images &#61; pyramid_demo(image) #做拉普拉斯金字塔必须用到高斯金字塔的结果level &#61; len(pyramid_images)for i in range(level-1, -1, -1):if (i-1) < 0:expand &#61; cv.pyrUp(pyramid_images[i], dstsize &#61; image.shape[:2])lpls &#61; cv.subtract(image, expand)cv.imshow("lapalian_down_"&#43;str(i&#43;1), lpls)else:expand &#61; cv.pyrUp(pyramid_images[i], dstsize &#61; pyramid_images[i-1].shape[:2])lpls &#61; cv.subtract(pyramid_images[i-1], expand)cv.imshow("lapalian_down_"&#43;str(i&#43;1), lpls)
src &#61; cv.imread(&#39;F:/test.jpg&#39;)
cv.namedWindow(&#39;input_image&#39;) #设置为WINDOW_NORMAL可以任意缩放
cv.imshow(&#39;input_image&#39;, src)
lapalian_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()

显示结果&#xff1a;
高斯金字塔&#xff1a;
在这里插入图片描述
拉普拉斯金字塔&#xff1a;
在这里插入图片描述

融合

图像融合的目的就是使两幅图像的重叠区域过渡自然且平滑。
常见融合方法&#xff1a;

  • 1&#xff09;加权平均法。这个很好理解&#xff0c;即简单的使用加权的方式从左边过渡到右边。这种方法效果一般&#xff0c;但算法实现极其简单&#xff0c;速度快。
  • 2&#xff09;羽化算法 。这种方法过渡会比加权平均法自然&#xff0c;但会造成不好的模糊效果。
  • 3&#xff09;拉普拉斯金字塔融合。有的地方也称为多分辨率融合算法。这种方法是将图像建立一个拉普拉斯金字塔&#xff0c;其中金字塔的每一层都包含了图像不同的频段。分开不同频段进行融合效果出奇的好。

图像拉普拉斯金字塔分解的目的是将源图像分别分解到不同的空间频带上&#xff0c;融合过程是在各空间频率层上分别进行的&#xff0c;这样就可以针对不同分解层的不同频带上的特征与细节&#xff0c;采用不同的融合算子以达到突出特定频带上特征与细节的目的。即有可能将来自不同图像的特征与细节融合在一起。

实例2&#xff1a;利用拉普拉斯金字塔实现融合

代码&#xff1a;

import cv2
import numpy as np,sys
A &#61; cv2.imread(&#39;F:/ninny.jpg&#39;)
B &#61; cv2.imread(&#39;F:/nero.jpg&#39;)
# generate Gaussian pyramid for A
G &#61; A.copy()
gpA &#61; [G]
for i in range(6):G &#61; cv2.pyrDown(G)gpA.append(G)
# generate Gaussian pyramid for B
G &#61; B.copy()
gpB &#61; [G]
for i in range(6):G &#61; cv2.pyrDown(G)gpB.append(G)
# generate Laplacian Pyramid for A
lpA &#61; [gpA[5]]
for i in range(5,0,-1):GE &#61; cv2.pyrUp(gpA[i])L &#61; cv2.subtract(gpA[i-1],GE)lpA.append(L)
# generate Laplacian Pyramid for B
lpB &#61; [gpB[5]]
for i in range(5,0,-1):GE &#61; cv2.pyrUp(gpB[i])L &#61; cv2.subtract(gpB[i-1],GE)lpB.append(L)
# Now add left and right halves of images in each level
#numpy.hstack(tup)
#Take a sequence of arrays and stack them horizontally
#to make a single array.
LS &#61; []
for la,lb in zip(lpA,lpB):rows,cols,dpt &#61; la.shapels &#61; np.hstack((la[:,:cols//2], lb[:,cols//2:]))# ls &#61; np.hstack((la[:, :cols // 4], lb[:, cols // 4: cols//2], la[:, cols//2:3 * cols//4], lb[:, 3*cols//4: ]))LS.append(ls)
# now reconstruct
ls_ &#61; LS[0]
for i in range(1,6):ls_ &#61; cv2.pyrUp(ls_)ls_ &#61; cv2.add(ls_, LS[i])
# image with direct connecting each half
real &#61; np.hstack((A[:,:cols//2],B[:,cols//2:]))
# real &#61; np.hstack((A[:,:cols//4],B[:,cols//4: cols//2], A[:, cols//2: 3*cols//4], B[:, 3*cols//4: ]))
cv2.imwrite(&#39;F:/ninny_nero.jpg&#39;,ls_)
cv2.imwrite(&#39;F:/nini_chaochao.jpg&#39;,real)

结果&#xff1a;
使用拉普拉斯融合后的图片&#xff1a;

在这里插入图片描述
直接拼接的照片&#xff1a;

在这里插入图片描述

问题和解决&#xff1a;

  • 金字塔输入的图像大小必须是2的n次方。
  • 调试程序的时候遇到这个报错&#xff1a;

File "H:/pycharm_pro/pyramid/pyr.py", line 39, in ls &#61; np.hstack((la[:, :cols / 4], lb[:, cols // 4: cols//2], la[:, cols//2:3 * cols//4], lb[:, 3*cols//4: ]))
TypeError: slice indices must be integers or None or have an __index__ method

因为单纯的使用除法得到的可能不是整数&#xff0c;但是在索引过程中必须要使用整数索引&#xff0c;所以只取整数部分即可。


推荐阅读
  • 针对图像分类任务的训练方案进行了优化设计。通过引入PyTorch等深度学习框架,利用其丰富的工具包和模块,如 `torch.nn` 和 `torch.nn.functional`,提升了模型的训练效率和分类准确性。优化方案包括数据预处理、模型架构选择和损失函数的设计等方面,旨在提高图像分类任务的整体性能。 ... [详细]
  • 浅析python实现布隆过滤器及Redis中的缓存穿透原理_python
    本文带你了解了位图的实现,布隆过滤器的原理及Python中的使用,以及布隆过滤器如何应对Redis中的缓存穿透,相信你对布隆过滤 ... [详细]
  • 基于iSCSI的SQL Server 2012群集测试(一)SQL群集安装
    一、测试需求介绍与准备公司计划服务器迁移过程计划同时上线SQLServer2012,引入SQLServer2012群集提高高可用性,需要对SQLServ ... [详细]
  • 本文介绍如何使用OpenCV和线性支持向量机(SVM)模型来开发一个简单的人脸识别系统,特别关注在只有一个用户数据集时的处理方法。 ... [详细]
  • 利用python爬取豆瓣电影Top250的相关信息,包括电影详情链接,图片链接,影片中文名,影片外国名,评分,评价数,概况,导演,主演,年份,地区,类别这12项内容,然后将爬取的信息写入Exce ... [详细]
  • 使用多项式拟合分析淘宝双11销售趋势
    根据天猫官方数据,2019年双11成交额达到2684亿元,再次刷新历史记录。本文通过多项式拟合方法,分析并预测未来几年的销售趋势。 ... [详细]
  • window下的python安装插件,Go语言社区,Golang程序员人脉社 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 本文介绍了如何利用 `matplotlib` 库中的 `FuncAnimation` 类将 Python 中的动态图像保存为视频文件。通过详细解释 `FuncAnimation` 类的参数和方法,文章提供了多种实用技巧,帮助用户高效地生成高质量的动态图像视频。此外,还探讨了不同视频编码器的选择及其对输出文件质量的影响,为读者提供了全面的技术指导。 ... [详细]
  • 如何将Python与Excel高效结合:常用操作技巧解析
    本文深入探讨了如何将Python与Excel高效结合,涵盖了一系列实用的操作技巧。文章内容详尽,步骤清晰,注重细节处理,旨在帮助读者掌握Python与Excel之间的无缝对接方法,提升数据处理效率。 ... [详细]
  • Python 序列图分割与可视化编程入门教程
    本文介绍了如何使用 Python 进行序列图的快速分割与可视化。通过一个实际案例,详细展示了从需求分析到代码实现的全过程。具体包括如何读取序列图数据、应用分割算法以及利用可视化库生成直观的图表,帮助非编程背景的用户也能轻松上手。 ... [详细]
  • 本文详细探讨了Oracle数据库中Number和Float数据类型的特性和使用方法。通过对比分析,解释了Number类型在精度和范围上的优势,以及Float类型在处理科学计算时的灵活性。文章还介绍了Number数据类型的语法结构及其在实际应用中的最佳实践,帮助读者更好地理解和选择合适的数据类型以满足不同的业务需求。 ... [详细]
  • 在多线程并发环境中,普通变量的操作往往是线程不安全的。本文通过一个简单的例子,展示了如何使用 AtomicInteger 类及其核心的 CAS 无锁算法来保证线程安全。 ... [详细]
  • 利用REM实现移动端布局的高效适配技巧
    在移动设备上实现高效布局适配时,使用rem单位已成为一种流行且有效的技术。本文将分享过去一年中使用rem进行布局适配的经验和心得。rem作为一种相对单位,能够根据根元素的字体大小动态调整,从而确保不同屏幕尺寸下的布局一致性。通过合理设置根元素的字体大小,开发者可以轻松实现响应式设计,提高用户体验。此外,文章还将探讨一些常见的问题和解决方案,帮助开发者更好地掌握这一技术。 ... [详细]
  • 使用Python代码高效生成大规模随机数据集(千万级) ... [详细]
author-avatar
安彬2502936127
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有