图像金字塔是由一幅图像的多个不同分辨率的子图构成的图像集合,该组图像由单个图像通过不断降采样所产生的,
最小的图像可能只有一个像素点
图像金字塔 是一系列以金字塔形状派列的、自底向上分辨率逐渐降低的图像集合
金子塔的底部是待处理的高分辨率的原始图像,而顶部则是其低分辨率的近似图像,每向上一级图像的宽和高都降低为原来的1/2
向下采样 可以通过不断的删除图像的偶数行和偶数列得到, 也可以先对图像进行滤波再删除偶数行和偶数列
采用高斯滤波器对向下采样的原始图像进行高斯滤波,得到的即是高斯金字塔,原始图像称为第0层,
第1次向下采样的结果图像称为第1层
向上采样 通常将图像的宽度和高度变为原来的2倍,意思是结果图像是原始图像大小的4倍
常见的向上采样,对像素点以补零的方式完成插值,通常都是在每列像素点的右侧插入值为零的列,在每行像素点的下方插入值为零的行
通过对向下采样和向上采样的描述可以知道,这两个操作是相反的操作,但是由于向下采样会丢失像素值,
这两种操作是不可逆的,也就是说对一幅图像先向下采样然后向上采样是不能恢复原始状态的
函数cv2.pyrDown(), 用于实现高斯金字塔中的向下采样
函数形式
dst = cv2.pyrDown( src [, dstsize [,borderType]])
dst目标图像
src原始图像
dstsize目标图像大小
borderType边界类型 , 默认为BORDER_DEFAULT, 且这里仅支持BORDER_DEFAULT
默认情况下输出图像大小为 Size((src.cols+1)/2 , (src.rows) /2 )
任何情况下图像尺寸必须满足条件: |dst.width *2 - src.cols| <= 2 |dst.height * 2 - src.rows | <= 2
向下取样:
1 import cv2
2 o = cv2.imread("/home/miao/dog.jpg" , cv2.IMREAD_GRAYSCALE)
3 r1 = cv2.pyrDown(o)
4 r2 = cv2.pyrDown(r1)
5 r3 = cv2.pyrDown(r2)
6 print("o.shape" , o.shape)
7 print("r1.shape" , r1.shape)
8 print("r2.shape" , r2.shape)
9 print("r3.shape" , r3.shape)
10 cv2.imshow("original" , o)
11 cv2.imshow("r1" , r1)
12 cv2.imshow("r2" , r2)
13 cv2.imshow("r3" , r3)
14 cv2.waitKey()
15 cv2.destroyAllWindows()
o.shape (200, 300) r1.shape (100, 150) r2.shape (50, 75) r3.shape (25, 38)
原图

r1

r2

r3

图片的大小变为原来的1/4,分辨率也变低
向上采样:
1 import cv2
2 o = cv2.imread("/home/miao/r3.png")
3 r1 = cv2.pyrUp(o)
4 r2 = cv2.pyrUp(r1)
5 r3 = cv2.pyrUp(r2)
6 print("o.shape" , o.shape)
7 print("r1.shape" , r1.shape)
8 print("r2.shape" , r2.shape)
9 print("r3.shape" , r3.shape)
10 cv2.imshow("original" , o)
11 cv2.imshow("r1" , r1)
12 cv2.imshow("r2" , r2)
13 cv2.imshow("r3" , r3)
14 cv2.waitKey()
15 cv2.destroyAllWindows()
o.shape (80, 121, 3) r1.shape (160, 242, 3) r2.shape (320, 484, 3) r3.shape (640, 968, 3)
原图

r1

r2

r3

可以看到对向下采样的图像,进行向上采样并不能恢复图像
拉普拉斯金字塔
我们希望通过对金字塔中的小图像进行向上采样获取完整的大尺寸高分辨率图像,则需要拉普拉斯金字塔
因为高斯滤波器的处理方法,会使图像丢失信息,所以为了在向上采样能够恢复较高分辨率的原始图像,
就要获取在采样的过程中丢失的信息,这些丢失的信息就构成了拉普拉斯金字塔
定义形式为:
Li = Gi - pyrUp( Gi + 1 ) 或者可以看成是 Li = Gi - pyrUp( pyrDown(Gi) )
式中
Li表示拉普拉斯金字塔中的第i层
Gi 表示高斯金字塔中的第i层
1 import cv2
2 o = cv2.imread("/home/miao/dog.jpg")
3 G0 = o
4 G1 = cv2.pyrDown(G0)
5 G2 = cv2.pyrDown(G1)
6 G3 = cv2.pyrDown(G2)
7 L0 = G0 - cv2.pyrUp(G1)
8 L1 = G1 - cv2.pyrUp(G2)
9 print("L0.shape" , L0.shape)
10 print("L1.shape" , L1.shape)
11 cv2.imshow("L0" , L0)
12 cv2.imshow("L1" , L1)
13 cv2.waitKey()
14 cv2.destroyAllWindows()
L0( L0 = G0 - cv2.pyrUp(G1) )

L1 ( L1 = G1 - cv2.pyrUp( G2) )

import cv2
import numpy as np
o = cv2.imread("/home/miao/dog.jpg")
#
G0 = o
G1 = cv2.pyrDown(G0)
G2 = cv2.pyrDown(G1)
#G3 = cv2.pyrDown(G2)
#
L0 = G0 - cv2.pyrUp(G1)
L1 = G1 - cv2.pyrUp(G2)
#L2 = G2 - cv2.pyrUp(G3)
#
RG0 = L0 + cv2.pyrUp(G1)
print("G0.shape" , G0.shape)
print("RG0.shape" ,RG0.shape)
result = RG0 - G0
result = abs(result)
print("|G0 - RG0|" , np.sum(result))
#
RG1 = L1 + cv2.pyrUp(G2)
print("G1.shape" ,G1.shape)
print("RG1.shape" , RG1.shape)
result = RG1 - G1
result = abs(result)
print("|G1 - RG1| " , np.sum(result))
#
#RG2 = L2 + cv2.pyrUp(G3)
#print("G2.shape" , G2.shape)
#print("RG2.shape" , RG2.shape)
#result = RG2 - G2
#resutl = abs(result)
#print("|RG2 - G2|" ,np.sum(result))
cv2.imshow("RG0" , RG0)
cv2.imshow("RG1" , RG1)
cv2.waitKey()
cv2.destroyAllWindows()
G0.shape (200, 300, 3) RG0.shape (200, 300, 3) |G0 - RG0| 0 G1.shape (100, 150, 3) RG1.shape (100, 150, 3) |G1 - RG1| 0
可以看到恢复的图像大小,通道数都一样
且两图像之差的绝对值为0 表示两幅图像完全一致
RG0

RG1

来源:https://www.cnblogs.com/miaorn/p/12295552.html