简介:图像金字塔是图像中多尺度表达的一种,最主要用于图像的分割,是一种以多分辨率来解释图像的有效但概念简单的结构。简单来说,图像金字塔就是用来进行图像缩放的。
进行图像缩放可以用图像金字塔,也可以使用resize函数进行缩放,后者效果更好。这里只是对图像金字塔做一些简单了解。
两种类型的金字塔:
①高斯金字塔:用于下采样。高斯金字塔是最基本的图像塔。原理:首先将原图像作为最底层图像G0(高斯金字塔的第0层),利用高斯核(5*5)对其进行卷积,然后对卷积后的图像进行下采样(去除偶数行和列)得到上一层图像G1,将此图像作为输入,重复卷积和下采样操作得到更上一层图像,反复迭代多次,形成一个金字塔形的图像数据结构,即高斯金字塔。
②拉普拉斯金字塔:用于重建图像,也就是预测残差,对图像进行最大程度的还原。比如一幅小图像重建为一幅大图,原理:用高斯金字塔的每一层图像减去其上一层图像上采样并高斯卷积之后的预测图像,得到一系列的差值图像即为 LP 分解图像。
两种类型的采样:
①上采样:就是图片放大(所谓上嘛,就是变大),使用PryUp函数。 上采样步骤:先将图像在每个方向放大为原来的两倍,新增的行和列用0填充,再使用先前同样的内核与放大后的图像卷积,获得新增像素的近似值。
②下采样:就是图片缩小(所谓下嘛,就是变小),使用PryDown函数。下采样将步骤:先对图像进行高斯内核卷积 ,再将所有偶数行和列去除。下采样的意思其实是把图像的尺寸缩减一半,行和列同时缩减一半。
总之,上、下采样都存在一个严重的问题,那就是图像变模糊了,因为缩放的过程中发生了信息丢失的问题。要解决这个问题,就得用拉普拉斯金字塔。
import cv2 as cv
import numpy as np
def pyrmaid_demo(image): # 高斯金字塔
pyrmaid_demo = [] # 建立一个空列表
temp = image.copy() # 拷贝图像
level = 3
for i in range(level):
dst = cv.pyrDown(temp) #先对图像进行高斯平滑,然后再进行降采样(将图像尺寸行和列方向缩减一半)
pyrmaid_demo.append(dst) #在列表末尾添加新的对象
cv.imshow("pyrmaid_demo"+str(i), dst)
temp = dst.copy()
return pyrmaid_demo
def laplace_demo(image): # 拉普拉斯金字塔
pyrmaid_images = pyrmaid_demo(image) #做拉普拉斯金字塔必须用到高斯金字塔的结果
level = len(pyrmaid_images)
for i in range(level-1, -1, -1):
if i-1 < 0: # 当i=0时,i-1<0,会导致数组溢出,因此要单独讨论
expand = cv.pyrUp(pyrmaid_images[i], dstsize=image.shape[:2])
lpls = cv.subtract(image, expand)
cv.imshow("pyrmaid_images"+str(i), lpls)
else:
expand = cv.pyrUp(pyrmaid_images[i], dstsize=pyrmaid_images[i-1].shape[:2]) # 将尺寸设置为上一层图像的尺寸
lpls = cv.subtract(pyrmaid_images[i-1], expand) # 相减
cv.imshow("pyrmaid_images" + str(i), lpls)
print("--------- Hello Python ---------")
src = cv.imread("D:/opencv/fang.jpg")
laplace_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()
pyrDown函数先对图像进行高斯平滑,然后再进行降采样(将图像尺寸行和列方向缩减一半)
pyrUp函数先对图像进行升采样(将图像尺寸行和列方向增大一倍),然后再进行高斯平滑
拉普拉斯金字塔时,图像大小必须是2的n次方*2的n次方,这么做的目的估计是为了能够使金字塔能够进行下去吧,否则在下采样到分辨率为奇数时就无法在下采样了(个人猜测)
附:
对图像进行缩放的最简单方法是调用resize函数
resize函数可以将源图像精确地转化为指定尺寸的目标图像。
要缩小图像,一般推荐使用CV_INETR_AREA来插值;若要放大图像,推荐使用CV_INTER_LINEAR。