目录
一 图像金字塔
在某些情况下,需要处理不同分辨率的(相同)图像。比如,在图像中搜索某些目标(比如人脸)的时候,不确定该目标在所述图像中会以多大的大小出现。在这种情况下,就需要创建一组具有不同分辨率的相同图像,并在所有图像中搜索目标。这些具有不同分辨率的图像集称为图像金字塔(最高分辨率的图像在底部,最低分辨率的图像在顶部,它看起来像一个金字塔)。
图像金字塔有两种,分别是高斯金字塔和拉普拉斯金字塔。
- ①高斯金字塔
高斯金字塔中的较高层次(低分辨率)是通过删除较低层次(高分辨率)图像中的连续行和列而形成的。然后,较高层次的每个像素由底层水平中具有高斯权重的 5 个像素的贡献形成的。面积减少到原始面积的四分之一。换句话说,就是下采样。图像变小,分辨率降低。
同理,在扩展时,每个级别中的面积变为 4 倍。即上采样。相对尺寸变大,但是分辨率不会增加,图像会变得更模糊。
可以使用 cv2.pyrDown() 和 cv2.pyrUp() 函数实现高斯金字塔。
- ②拉普拉斯金字塔
拉普拉斯金字塔由高斯金字塔组成。没有专用功能。拉普拉斯金字塔图像仅与边缘图像类似。大部分元素都是零。它们用于图像压缩。
二 涉及的函数
pyrDown(src[, dst[, dstsize[, borderType]]]) -> dst
pyrUp(src[, dst[, dstsize[, borderType]]]) -> dst
三 实践
①高斯金字塔
- 代码
import numpy as np
import cv2
import matplotlib.pyplot as plt
def dealImg(img):
b, g, r = cv2.split(img)
img_rgb = cv2.merge([r, g, b])
return img_rgb
def dealImageResult(img_path):
im = cv2.imread(img_path)
# 下采样
im_down1 = cv2.pyrDown(im)
im_down2 = cv2.pyrDown(im_down1)
# 上采样
img_up1 = cv2.pyrUp(im_down2)
img_up2 = cv2.pyrUp(img_up1)
fig = plt.figure(figsize=(8, 10))
titles = ["img", " down1", "down2", "up1", 'up2']
im = dealImg(im)
im_down1 = dealImg(im_down1)
im_down2 = dealImg(im_down2)
img_up1 = dealImg(img_up1)
img_up2 = dealImg(img_up2)
images = [im, im_down1, im_down2, img_up1, img_up2]
for i in range(5):
plt.subplot(2, 3, i + 1), plt.imshow(images[i])
plt.title("{}".format(titles[i]), color="green", fontsize=20, ha='center')
# plt.xticks([]), plt.yticks([])
plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=0.3, hspace=0)
# plt.tight_layout()
plt.show()
fig.savefig('test_results.jpg', bbox_inches='tight')
if __name__ == '__main__':
dealImageResult("2.jpg")
pass
- 结果图
注意:img不等于up2,虽然尺寸相同,但是因为一旦降低分辨率,就会丢失信息。可以看出up2的结果模糊了。
②拉普拉斯金字塔
- 代码
import numpy as np
import cv2
import matplotlib.pyplot as plt
def dealImg(img):
b, g, r = cv2.split(img)
img_rgb = cv2.merge([r, g, b])
return img_rgb
def dealImageResult(img_path):
im = cv2.imread(img_path)
# 下采样
im_down = cv2.pyrDown(im)
# 上采样
img_up = cv2.pyrUp(im_down)
# 拉普拉斯金字塔
Lp = cv2.subtract(im, img_up)
# 或者
Lp_1 = im - img_up
fig = plt.figure(figsize=(8, 10))
titles = ["img", " im_down", "img_up", "Lp", 'Lp_1']
im = dealImg(im)
im_down = dealImg(im_down)
img_up = dealImg(img_up)
Lp = dealImg(Lp)
Lp_1 = dealImg(Lp_1)
images = [im, im_down, img_up, Lp, Lp_1]
for i in range(5):
plt.subplot(2, 3, i + 1), plt.imshow(images[i])
plt.title("{}".format(titles[i]), color="green", fontsize=20, ha='center')
# plt.xticks([]), plt.yticks([])
plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=0.3, hspace=0)
# plt.tight_layout()
plt.show()
fig.savefig('test_results.jpg', bbox_inches='tight')
if __name__ == '__main__':
dealImageResult("2.jpg")
pass
- 结果图
注意:图像尺寸最好是 2 的整次幂,如 256,512 等等。否则的话,在金字塔向上的过程中图像的尺寸会不等,这会导致在拉普拉斯金字塔处理时由于不同尺寸矩阵相减操作而报错。
前文回顾