一、背景
有关高斯金字塔、拉普拉斯金字塔的相关背景知识可以参考
OpenCV之图像金字塔与图像融合
二、图像融合
图像金字塔一个典型的应用就是图像融合。图像融合的实现步骤为:
- 读入两幅大小相同的图像 img1 img2;
- 构建 img1 img2的 高斯金字塔,层数根据需要设定(本实验为7层);
- 根据高斯金字塔和拉普拉斯金字塔的关系,推出拉普拉斯金字塔的Li(也为7层,第一层大小和原图相同);
- 在拉普拉斯图层的每一层进行图像融合;
- 根据融合后的图像金字塔重建原始图像。
三、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()
四、实验结果
原图:
融合后图像:
生硬连接结果:
这么一看效果还是非常棒的~