图像金字塔是图像多尺度表达的一种,是一种以多分辨率来解释图像的有效但概念简单的结构。一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐步降低,且来源于同一张原始图的图像集合。其通过梯次向下采样获得,直到达到某个终止条件才停止采样。我们将一层一层的图像比喻成金字塔,层级越高,则图像越小,分辨率越低。
图像金字塔主要有高斯金字塔和拉普拉斯金字塔两种类型。
高斯金字塔(Gaussianpyramid):用于降采样,是主要的图像金字塔。
其原理为:首先将原图像作为最底层图像Image0(高斯金字塔的第0层),利用高斯核(5*5)对其进行卷积,然后对卷积后的图像进行降采样(去除偶数行和列)得到上一层图像Image1,将此图像作为输入,重复卷积和下采样操作得到更上一层图像,反复迭代多次,形成一个金字塔形的图像数据结构,即高斯金字塔。
其代码如下:
def pyramid_demo(image): # 高斯金字塔
level = 3 # 金字塔层数为3
temp = image.copy() # 复制图像
pyramid_image = [] # 创建一个空列表
for i in range(level):
dst = cv.pyrDown(temp) # 先对图像进行高斯平滑,然后再进行降采样(将图像尺寸行和列方向缩减一半)
# append()函数:
# 描述:在列表ls最后(末尾)添加一个元素object
# 语法:ls.append(object) -> None 无返回值
pyramid_image.append(dst) # 在列表末尾添加新的对象
cv.imshow("pyramid_down_" + str(i), dst)
temp = dst.copy()
return pyramid_image
拉普拉斯金字塔(Laplacianpyramid):用来从金字塔底层图像重建上层未采样图像,在数字图像处理中也就是预测残差,可以对图像进行最大程度的还原,配合高斯金字塔一起使用。
其原理为:用高斯金字塔的每一层图像减去其上一层图像上采样并高斯卷积之后的预测图像,得到一系列的差值图像即为 LP 分解图像。
其代码如下:
def Laplace_demo(image): # 拉普拉斯金字塔
pyramid_image = pyramid_demo(image) # 做拉普拉斯金字塔必须用到高斯金字塔的结果
level = len(pyramid_image)
for i in range(level-1, -1, -1): # 从后往前,2,1,0
if (i-1) < 0: # 原图
expand = cv.pyrUp(pyramid_image[i], dstsize=image.shape[:2]) # 上采样
lps = cv.subtract(image, expand) # 使用高斯金字塔上一个减去当前上采样获取的结果,才是拉普拉斯金字塔
cv.imshow("Laplace_down_" + str(i), lps)
else:
expand = cv.pyrUp(pyramid_image[i], dstsize=pyramid_image[i-1].shape[:2])
lps = cv.subtract(pyramid_image[i-1], expand)
cv.imshow("Laplace_down_"+str(i), lps)
这次我们需要用到的图像的宽和高必须为2^n(n为正整数),否则会报错,这次我们用到的是莱娜的图像,原图为:
经过拉普拉斯金字塔后的效果为:
能勉强看到一些轮廓。
注:两者的简要区别:高斯金字塔用来向下采样图像,而拉普拉斯金字塔则用来从金字塔底层图像中向上采样重建一个图像。
import cv2 as cv # 导入opencv模块
import numpy as np # 导入数学函数库
def pyramid_demo(image): # 高斯金字塔
level = 3 # 金字塔层数为3
temp = image.copy() # 复制图像
pyramid_image = [] # 创建一个空列表
for i in range(level):
dst = cv.pyrDown(temp) # 先对图像进行高斯平滑,然后再进行降采样(将图像尺寸行和列方向缩减一半)
# append()函数:
# 描述:在列表ls最后(末尾)添加一个元素object
# 语法:ls.append(object) -> None 无返回值
pyramid_image.append(dst) # 在列表末尾添加新的对象
cv.imshow("pyramid_down_" + str(i), dst)
temp = dst.copy()
return pyramid_image
def Laplace_demo(image): # 拉普拉斯金字塔
pyramid_image = pyramid_demo(image) # 做拉普拉斯金字塔必须用到高斯金字塔的结果
level = len(pyramid_image)
for i in range(level-1, -1, -1): # 从后往前,2,1,0
if (i-1) < 0: # 原图
expand = cv.pyrUp(pyramid_image[i], dstsize=image.shape[:2]) # 上采样
lps = cv.subtract(image, expand) # 使用高斯金字塔上一个减去当前上采样获取的结果,才是拉普拉斯金字塔
cv.imshow("Laplace_down_" + str(i), lps)
else:
expand = cv.pyrUp(pyramid_image[i], dstsize=pyramid_image[i-1].shape[:2])
lps = cv.subtract(pyramid_image[i-1], expand)
cv.imshow("Laplace_down_"+str(i), lps)
print("------------hello python!------------")
src = cv.imread("D:/opencv3/image/lena.png")
cv.namedWindow("input_image", cv.WINDOW_AUTOSIZE)
cv.imshow("input_image", src)
# pyramid_demo(src)
Laplace_demo(src)
cv.waitKey(0)
cv.destroyAllWindows() # 释放所有窗口