本文将主要介绍 图像金字塔中的 两类常见图像金字塔:高斯金字塔与拉普帕斯金字塔
图像金字塔是图像中多尺度表达的一种,最主要用于图像的分割,是一种以多分辨率来解释图像的有效但概念简单的结构。简单来说, 图像金字塔是同一图像不同分辨率的子图集合.
图像金字塔最初用于机器视觉和图像压缩,一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐步降低,且来源于同一张原始图的图像集合。其通过梯次向下采样获得,直到达到某个终止条件才停止采样。金字塔的底部是待处理图像的高分辨率表示,而顶部是低分辨率的近似。我们将一层一层的图像比喻成金字塔,层级越高,则图像越小,分辨率越低。
高斯金字塔 ( Gaussian pyramid): 用来向下/降采样,主要的图像金字塔
拉普拉斯金字塔(Laplacian pyramid): 用来从金字塔低层图像重建上层未采样图像,在数字图像处理中也即是预测残差,可以对图像进行最大程度的还原,配合高斯金字塔一起使用。
高斯金字塔是通过高斯平滑和亚采样获得一系列下采样图像.
原理非常简单, 如下图所示:
原始图像 M * N -> 处理后图像 M/2 * N/2.
每次处理后, 结果图像是原来的1/4.
注意: 向下采样会丢失图像信息.
import cv2
import numpy as np
img = cv2.imread('./lena.png')
print(img.shape)
dst = cv2.pyrDown(img)
print(dst.shape)
cv2.imshow('img', img)
cv2.imshow('dst', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 向上采样
# 向下采样
import cv2
import numpy as np
img = cv2.imread('./lena.png')
print(img.shape)
dst2 = cv2.pyrUp(img)
print(dst.shape)
cv2.imshow('img', img)
cv2.imshow('dst2', dst2)
cv2.waitKey(0)
cv2.destroyAllWindows()
## 代码
import cv2
import numpy as np
img=cv2.imread('./lena.png')
print(img.shape)
#分辨率减小操作,下采样
dst=cv2.pyrDown(img)
#分辨率增加操作,上采样
dst2=cv2.pyrUp(dst)
print(dst.shape)
cv2.imshow('img',img)
# cv2.imshow('dst',dst)
cv2.imshow('dst2',dst2)
cv2.waitKey(0)
cv2.destroyAllWindows()
图中最小的为向下采样的结果,中等的为原图,较大的为向上采样的结果
在根据向上和向下取样的原理, 我们能够发现图像在变大变小的过程中是有信息丢失的. 即使把图片变回原来大小,图片也不是原来的图片了, 而是损失了一定的信息.
# 研究采样中图像的损失
import cv2
import numpy as np
img = cv2.imread('./lena.png')
# 先放大, 再缩小
dst = cv2.pyrUp(img)
dst = cv2.pyrDown(dst)
cv2.imshow('img', img)
cv2.imshow('dst', dst)
cv2.imshow('loss', img - dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
将降采样之后的图像再进行上采样操作,然后与之前还没降采样的原图进行做差得到残差图!为还原图像做信息的准备!
也就是说,拉普拉斯金字塔是通过源图像减去先缩小后再放大的图像的一系列图像构成的。保留的是残差!
## 代码
img=cv2.imread('./lena.png')
print(img.shape)
#第一层拉普拉斯金字塔
#分辨率减小操作,下采样
dst=cv2.pyrDown(img)
#分辨率增加操作,上采样
dst=cv2.pyrUp(dst)
# 原图减去高斯金字塔的图像的差值就是拉普拉斯金字塔
lap0=img-dst
#第二层拉普拉斯金字塔
#分辨率减小操作,下采样
dst1=cv2.pyrDown(dst)
#分辨率增加操作,上采样
dst1=cv2.pyrUp(dst1)
# 原图减去高斯金字塔的图像的差值就是拉普拉斯金字塔
lap1=dst-dst1
cv2.imshow('img',img)
cv2.imshow('lap',lap0)
cv2.imshow('lap1',lap1)
cv2.waitKey(0)
cv2.destroyAllWindows()