python+opencv基于图像金字塔实现图像融和
图像金字塔主要涉及两个函数:cv.pyrUp()(图像尺寸变小),cv.pyrDown()(图像尺寸变大,但是会模糊)
图像金字塔主要有两个类型:高斯金字塔和拉普拉斯金字塔
关于定义和讲解在链接:图像金字塔
金字塔图像融和的两个重要作用:
1、实现两个图像的无缝连接,就如下面的苹果和橘子
2、图像压缩,利用小图形(被高斯金字塔变换后的图像)和几层拉普拉斯金字塔表示大图像信息(拉普拉斯金字塔即使图像很大,由于大部分都是黑色,可以认为是0,因此压缩后数量很小)
苹果和橘子的例子的原始图像和融合后的效果图如下:
具体代码以及详细注释:
import cv2 as cv import numpy as np from matplotlib import pyplot as plt #读取图片 A = cv.imread('img/apple.jpg') B = cv.imread('img/orange.jpg') #将苹果进行高斯金字塔处理,共六级 G = A.copy() gpA = [G] # 将原图加入到列表中,在后面进行拉普拉斯金字塔处理的时候会用到 for i in range(6): G = cv.pyrDown(G) gpA.append(G) #将橘子进行高斯金字塔处理,共六级 G = B.copy() gpB = [G] # 将原图加入到列表中,在后面进行拉普拉斯金字塔处理的时候会用到 for i in range(6): G = cv.pyrDown(G) gpB.append(G) #根据高斯金字塔计算拉普拉斯金字塔,共处理五级 #共6张图 一个高斯金字塔 五个拉普拉斯金字塔 lpA = [gpA[5]] # 将高斯金字塔的第六张图像存进去,后面会用到 for i in range(5, 0, -1): GE = cv.pyrUp(gpA[i]) # 对高斯金字塔进行放大操作 # 用上一级的高斯金字塔,减去放大后的高斯金字塔,得到拉普拉斯金字塔 L = cv.subtract(gpA[i-1], GE) lpA.append(L) #根据高斯金字塔计算拉普拉斯金字塔,共处理五级 #共6张图 一个高斯金字塔 五个拉普拉斯金字塔 lpB = [gpB[5]] for i in range(5, 0, -1): GE = cv.pyrUp(gpB[i]) #对高斯金字塔进行放大操作 # 用上一级的高斯金字塔,减去放大后的高斯金字塔,得到拉普拉斯金字塔 L = cv.subtract(gpB[i-1], GE) lpB.append(L) #对苹果和橘子的拉普拉斯金字塔进行融合 #取苹果的左边一半,橘子的右边一半,因为像素不接受小数,所以要整除 LS = [] for la, lb in zip(lpA, lpB): rows, cols, dpt = la.shape ls = np.hstack((la[:,0:cols//2,:], lb[:, cols//2:,:])) LS.append(ls) ls_ = LS[0] # 将存放在列表里的高斯金字塔出去来 for i in range(1, 6): ls_ = cv.pyrUp(ls_) #对高斯图像进行放大 # 再加上拉普拉斯金字塔图像,构成新的图像 ls_ = cv.add(ls_, LS[i]) #直接原始图像拼接的效果 real = np.hstack((A[:,:cols//2], B[:, cols//2:])) cv.imshow('apple', A) cv.imshow('orange', B) cv.imshow('direct', real) cv.imshow('pyramid', ls_) cv.waitKey(0) cv.destroyAllWindows()