Python+OpenCV实现基于金字塔的图像融合

一、背景

有关高斯金字塔、拉普拉斯金字塔的相关背景知识可以参考
OpenCV之图像金字塔与图像融合

二、图像融合

图像金字塔一个典型的应用就是图像融合。图像融合的实现步骤为:

  1. 读入两幅大小相同的图像 img1 img2;
  2. 构建 img1 img2的 高斯金字塔,层数根据需要设定(本实验为7层);
  3. 根据高斯金字塔和拉普拉斯金字塔的关系,推出拉普拉斯金字塔的Li(也为7层,第一层大小和原图相同);
  4. 在拉普拉斯图层的每一层进行图像融合;
  5. 根据融合后的图像金字塔重建原始图像。

三、Python+OpenCV实现图像金字塔融合源码

# -*- coding: utf-8 -*-
from cv2 import cv2
import numpy as np

# 这里图像的尺寸必须为2的n次幂
A = cv2.imread('C:/Users/HP/Desktop/apple.png')
A = cv2.resize(A, (512,512), interpolation=cv2.INTER_CUBIC) 
B = cv2.imread('C:/Users/HP/Desktop/orange.png')
B = cv2.resize(B, (512,512), interpolation=cv2.INTER_CUBIC)

# 生成8层的高斯金字塔gpA
G = A.copy()
gpA = [G]
for i in range(7):
    # 进行7次高斯模糊+下采样
    G = cv2.pyrDown(G)
    # 把每次高斯模糊+下采样的结果送给gpA
    gpA.append(G)

# 生成8层的高斯金字塔gpB
G = B.copy()
gpB = [G]
for i in range(7):
    # 进行7次高斯模糊+下采样
    G = cv2.pyrDown(G)
    # 把每次高斯模糊+下采样的结果送给gpB
    gpB.append(G)

# 把两个高斯金字塔进行合并
LR = []
# zip(lpA,lpB)把两个高斯金字塔各层的两个图像组合成一个元组,然后各元组构成一个大zip
# 对于各元组中的两个图像
for la,lb in zip(gpA,gpB):
    # 取la或lb的尺寸皆可
    rows,cols,dpt = la.shape
    # 利用np.hstack将这两个图像“一半一半”地拼接起来
    # 取la的左边一半和lb的右边一半拼成一个融合后的图,结果赋给ls
    lr = np.hstack((la[:,0:cols//2], lb[:,cols//2:]))
    # 两个拉普拉斯金字塔各层图像融合后的结果赋给LS
    LR.append(lr)

# 用融合后的拉普拉斯金字塔重构出最终图像
# 初始化ls为融合后拉普拉斯金字塔的最高层
# 下面的循环结束后ls就是要求的最终结果图像
lr = LR[7]
for i in range(6,-1,-1):
    # 每层图像先上采样,再和当前层的下一层图像相加,结果再赋给ls
    lr = cv2.pyrUp(lr)
    lr = cv2.add(lr, LR[i])
#---------------------------------------------------------------------------------------------------
# 生成8层拉普拉斯金字塔
# 从顶层开始构建
# 顶层即高斯金字塔的顶层
lpA = [gpA[7]]
# 7 6 5 4 3 2 1
for i in range(7,0,-1):
    # 从顶层开始,不断上采样
    GE = cv2.pyrUp(gpA[i])
    # 用下一层的高斯减去上层高斯的上采样
    L = cv2.subtract(gpA[i-1],GE)
    # 结果送给拉普拉斯金字塔
    lpA.append(L)
 
lpB = [gpB[7]]
for i in range(7,0,-1):
    GE = cv2.pyrUp(gpB[i])
    L = cv2.subtract(gpB[i-1],GE)
    lpB.append(L)

# 把两个拉普拉斯金字塔进行合并
LS = []
# zip(lpA,lpB)把两个拉普拉斯金字塔各层的两个图像组合成一个元组,然后各元组构成一个大zip
# 对于各元组中的两个图像
for la,lb in zip(lpA,lpB):
    # 取la或lb的尺寸皆可
    rows,cols,dpt = la.shape
    # 利用np.hstack将这两个图像“一半一半”地拼接起来
    # 取la的左边一半和lb的右边一半拼成一个融合后的图,结果赋给ls
    ls = np.hstack((la[:,0:cols//2], lb[:,cols//2:]))
    # 两个拉普拉斯金字塔各层图像融合后的结果赋给LS
    LS.append(ls)

# 用融合后的拉普拉斯金字塔重构出最终图像
# 初始化ls为融合后拉普拉斯金字塔的最高层
# 下面的循环结束后ls就是要求的最终结果图像
ls = LS[0]
for i in range(1,8):
    # 每层图像先上采样,再和当前层的下一层图像相加,结果再赋给ls
    ls = cv2.pyrUp(ls)
    ls = cv2.add(ls, LS[i])

with_pyramid = lr + ls

# 不用金字塔融合,直接生硬地连接两幅原始图像
without_pyramid = np.hstack((A[:,:cols//2],B[:,cols//2:]))

# 对比一下结果
cv2.imshow("with_pyramid",with_pyramid)
cv2.imshow("without_pyramid",without_pyramid)
 
# 按任意键关闭所有窗口
cv2.waitKey()
cv2.destroyAllWindows()

四、实验结果

原图:

在这里插入图片描述
在这里插入图片描述

融合后图像:

在这里插入图片描述

生硬连接结果:

在这里插入图片描述
这么一看效果还是非常棒的~

Python是一种高级编程语言,而OpenCV是一个广泛应用于计算机视觉任务的开源库。全景图拼接是指将多张重叠的图像拼接成一张具有更宽视野的图像。 为了实现全景图拼接,我们可以使用PythonOpenCV的组合来完成任务。首先,我们需要加载所有待拼接的图像。可以使用OpenCV的`cv2.imread()`函数读取每张图像,并将其存储为一个图像列表。 接下来,我们需要对每个图像进行特征提取。可以使用OpenCV的`cv2.SIFT()`或`cv2.SURF()`函数来检测并提取图像中的特征点和描述符。 然后,我们需要在所有图像中找到匹配的特征点。可以使用OpenCV的`cv2.BFMatcher()`函数将特征点进行匹配,并得到最佳的匹配结果。 接下来,我们需要估计每个图像之间的变换关系。可以使用OpenCV的`cv2.findHomography()`函数来估计单应矩阵(homography matrix)。这个矩阵可以描述一个坐标系到另一个坐标系的映射关系。 然后,我们需要将所有图像根据估计的变换关系进行拼接。可以使用OpenCV的`cv2.warpPerspective()`函数来将每个图像进行透视变换,并将它们拼接在一起。 最后,我们需要进行图像融合,以消除拼接过程中可能出现的不连续边缘和重叠区域的不连续性。可以使用OpenCV的多种图像融合技术,例如线性混合或拉普拉斯金字塔融合等。 通过以上步骤,我们可以实现PythonOpenCV的全景图拼接。最后,将所有图像拼接结果保存到一个.tar文件中,以方便后续使用和参考。 总结起来,我们通过Python的编程能力和OpenCV的图像处理功能,可以实现全景图拼接,并将结果保存到一个.tar文件中,以提高图像的观看体验和使用灵活性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Polaris_T

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值