图像金字塔
图像金字塔有两种。 1) 高斯金字塔和 2) 拉普拉斯金字塔
高斯金字塔中的更高级别(低分辨率)是通过删除低级别(更高分辨率)图像中的连续行和列而形成的。然后更高级别的每个像素由具有高斯权重的底层级别的5个像素的贡献形成。通过这样做,M×N 图像变为 M/2×N/2 图像。因此面积减少到原来面积的四分之一。它被称为八度。随着我们在金字塔中的上层(即分辨率降低),相同的模式仍在继续。同样地,在扩展时,面积在每一级变为 4 倍。我们可以使用 cv.pyrDown() 和 cv.pyrUp()函数找到高斯金字塔
1. 高斯金字塔
cv.pyrDown()Python中用法:
dst = cv.pyrDown( src[, dst[, dstsize[, borderType]]] )
模糊图像并对其进行下采样。
默认情况下,输出图像的大小计算为 Size((src.cols+1)/2, (src.rows+1)/2),但无论如何,应满足以下条件:
∣
d
s
t
s
i
z
e
.
w
i
d
t
h
∗
2
−
s
r
c
.
c
o
l
s
∣
≤
2
|dstsize.width∗2−src.cols|≤2
∣dstsize.width∗2−src.cols∣≤2
∣
d
s
t
s
i
z
e
.
h
e
i
g
h
t
∗
2
−
s
r
c
.
r
o
w
s
∣
≤
2
|dstsize.height∗2−src.rows|≤2
∣dstsize.height∗2−src.rows∣≤2
该函数执行高斯金字塔构造的下采样步骤。首先,它将源图像与内核进行卷积:
1
256
[
1
4
6
4
1
4
16
24
16
4
6
24
36
24
6
4
16
24
16
4
1
4
6
3
1
]
(1)
\frac{1}{256} \begin{bmatrix} 1&4&6&4&1\\ 4&16&24&16&4\\ 6&24&36&24&6\\ 4&16&24&16&4\\ 1&4&6&3&1\\ \end{bmatrix}\tag{1}
2561⎣⎢⎢⎢⎢⎡1464141624164624362464162416314641⎦⎥⎥⎥⎥⎤(1)
然后,它通过删除偶数行和列来对图像进行下采样。
pyrUp()Python中用法:
dst = cv.pyrUp( src[, dst[, dstsize[, borderType]]] )
对图像进行上采样,然后对其进行模糊处理。
默认情况下,输出图像的大小计算为 Size(src.cols*2, (src.rows*2),但在任何情况下,都应满足以下条件:
∣
d
s
t
s
i
z
e
.
w
i
d
t
h
−
s
r
c
.
c
o
l
s
∗
2
∣
≤
(
d
s
t
s
i
z
e
.
w
i
d
t
h
m
o
d
2
)
|dstsize.width−src.cols∗2|≤(dstsize.widthmod2)
∣dstsize.width−src.cols∗2∣≤(dstsize.widthmod2)
∣
d
s
t
s
i
z
e
.
h
e
i
g
h
t
−
s
r
c
.
r
o
w
s
∗
2
∣
≤
(
d
s
t
s
i
z
e
.
h
e
i
g
h
t
m
o
d
2
)
|dstsize.height−src.rows∗2|≤(dstsize.heightmod2)
∣dstsize.height−src.rows∗2∣≤(dstsize.heightmod2)
该函数执行基于高斯金字塔的上采样步骤,尽管它实际上可以用于构造拉普拉斯金字塔。首先,它通过注入零行和零列对源图像进行上采样,然后使用与 pyrDown 乘以 4 相同的内核对结果进行卷积。
2. 拉普拉斯金字塔
构造流程如下:G为高斯层级
# 为 A 生成高斯金字塔
G = A.copy()
gpA = [G]
for i in range(6):
G = cv.pyrDown(G)
gpA.append(G)
# 为 B 生成高斯金字塔
G = B.copy()
gpB = [G]
for i in range(6):
G = cv.pyrDown(G)
gpB.append(G)
# 为 A 生成拉普拉斯金字塔
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)
# 为 B 生成拉普拉斯金字塔
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:int(cols / 2)], lb[:, int(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[:, :int(cols / 2)], B[:, int(cols / 2):]))
ls_ = cv.cvtColor(ls_, cv.COLOR_BGR2RGB)
real = cv.cvtColor(real, cv.COLOR_BGR2RGB)
plt.subplot(121), plt.imshow(ls_), plt.title("Pyramid_blending")
plt.axis("off")# 关闭坐标轴
plt.subplot(122), plt.imshow(real), plt.title("Direct_blending")
plt.axis("off")
# cv.imwrite('Pyramid_blending2.jpg', ls_)
# cv.imwrite('Direct_blending.jpg', real)
plt.show()
结果如下: