参考:图像金字塔
:【OpenCV入门】第十五弹:图像金字塔
通常情况下,我们使用的是固定大小的图像,但在某种情况下,我们需要处理不同分辨率的图像。例如。在人脸识别中,我们是无法确定人脸在图像中的大小的。这种情况下,我们需要创建一组具备不同分辨率的相同图像集,并且在这个图像集中搜索对象。这个具有不同分辨率的图像集称为图像金字塔。
个人感觉是像是图像的缩放,在opencv中,关于图像金字塔的操作,有pyrup(),pyrdown()操作,分别完成上采样和下采样。
有两种金字塔,高斯金字塔和拉普拉斯金字塔。
高斯金字塔:用于下采样,其中高阶(低分辨率)是通过去除低阶(高分辨率)图像中连续的行和列而形成的。
cv.pyrDown()效果
高斯核:
为了获取第 G_i+1层图像,我们采用下列方法:
对图像下采样:
- 对图像G_i进行高斯内核卷积
- 将所有偶数行和列去除
结合上图,可看到结果图像只有原图像的1/4。通过对输入图像G_i(原始图像)不停迭代以上步骤就会得到整个金字塔。同时我们也可以看到,向下取样会逐渐丢失图像的信息。即,下采样会缩小图像
对图像上采样:
- 将图像在每个方向扩大为原来的两倍,新增的行和列以0填充
- 使用先前同样的内核**(乘以4)与放大后的图像卷积,获得 “新增像素”的近似值( **
得到的图像即为放大后的图像,但是与原来的图像相比会发觉比较模糊,因为在缩放的过程中已经丢失了一些信息,如果想在缩小和放大整个过程中减少信息的丢失,这些数据形成了拉普拉斯金字塔。
import cv2
import numpy as np
import matplotlib.pyplot as plt
import pylab
pylab.rcParams['figure.figsize'] = (20.0, 10.0)
img = cv2.imread('E:/a1.png')
r1 = cv2.pyrDown(img)
r2 = cv2.pyrDown(r1)
r3 = cv2.pyrDown(r2)
print(img.shape)
print(r1.shape)
print(r2.shape)
plt.subplot(1,4,1),plt.imshow(img)
plt.title('img'),plt.xticks([]),plt.yticks([])
plt.subplot(1,4,2),plt.imshow(r1)
plt.title('r1'),plt.xticks([]),plt.yticks([])
plt.subplot(1,4,3),plt.imshow(r2)
plt.title('r2'),plt.xticks([]),plt.yticks([])
plt.subplot(1,4,4),plt.imshow(r3)
plt.title('r3'),plt.xticks([]),plt.yticks([])
plt.show()
##输出结果
(923, 1443, 3)
(462, 722, 3)
(231, 361, 3)
(116, 181, 3)
输出结果:
可看到分辨率依次为1/4的关系。
pyrDown()原理与pyrUp()原理
import cv2
import numpy as np
import matplotlib.pyplot as plt
import pylab
img_1 = np.random.randint(0,10,size=100,dtype=np.uint8)#数据类型要注意
img_1 = img_1.reshape(10,10)
print(img_1)
kernel = np.array([[1,4,6,4,1],
[4,16,24,16,4],
[6,24,36,24,6],
[4,16,24,16,4],
[1,4,6,4,1]])
kernel = kernel/256
dst = cv2.filter2D(img_1,-1,kernel) #与高斯核卷积
print(dst)
dst_2 = np.zeros((5,5),dtype=np.uint8)
for i in range(10): #除去偶数行和偶数列
if i%2 == 0:
for j in range(10):
if j%2 == 0:
dst_2[int(i/2),int(j/2)] = dst[i,j]
print(dst_2)
dst_3 = np.zeros((10,10),dtype=np.uint8)
for i in range(10): #偶数行和偶数列插0
if i%2 == 0:
for j in range(10):
if j%2 == 0:
dst_3[i,j] = dst_2[int(i/2),int(j/2)]
print(dst_3)
注意,PryUp和PryDown不是互逆的。得到的图像即为放大后的图像,但是与原来的图像相比会发觉比较模糊,因为在缩放的过程中已经丢失了一些信息,如果想在缩小和放大整个过程中减少信息的丢失,这些数据形成了拉普拉斯金字塔。