OpenCV开发教程之图像金字塔

28人浏览 / 0人评论 / 添加收藏

图像金字塔是计算机视觉中用于处理图像多尺度特征的核心技术。它就像一座从下到上、由大到小的图像“叠塔”,让你能在不同尺度上分析同一张图像,这对于识别场景里大小不一的目标至关重要。

OpenCV 中的图像金字塔主要分为高斯金字塔(Gaussian Pyramid)和拉普拉斯金字塔(Laplacian Pyramid)两类。

🏔️ 高斯金字塔 (Gaussian Pyramid):图像的“缩放器”

高斯金字塔的核心是下采样(缩小)上采样(放大)。它通过一系列处理,生成一系列尺寸递减的图像。

下采样 (Downsample):使用 cv2.pyrDown() 函数,它会先对图像进行高斯模糊,然后移除所有偶数行和偶数列,使图像的宽和高都变为原来的1/2,面积变为原来的1/4。

上采样 (Upsample):使用 cv2.pyrUp() 函数,它会先将图像尺寸放大到原来的两倍,然后用特定的高斯内核对新增的像素进行插值,填补空缺,使其看起来更平滑。

需要注意:无论是先上采样再下采样,还是反过来,都无法完全恢复到原始图像,因为下采样过程会永久性地丢失部分细节信息。

🧩 拉普拉斯金字塔 (Laplacian Pyramid):细节的“还原器”

拉普拉斯金字塔并非独立存在,它基于高斯金字塔构建,其核心是“保存丢失的细节”。它专门用来捕捉在下采样过程中丢失的高频细节(如边缘和纹理),这对于图像压缩和重建至关重要。

构建方法:OpenCV 没有直接创建拉普拉斯金字塔的函数,你需要手动计算。每一层拉普拉斯图像 Li 是由高斯金字塔的当前层 Gi 减去其下一层(Gi+1)先上采样再高斯模糊后的图像来得到的。

数学公式Li = Gi - pyrUp(Gi+1)

在实际代码中,由于上采样后尺寸可能与原始层不完全匹配,通常需要先用 cv2.resize() 函数调整尺寸,使两者一致后再相减。

💻 OpenCV核心函数用法

这是实现上述功能的核心代码示例:

# 1. 高斯金字塔:下采样 (缩小)
smaller_img = cv2.pyrDown(img)

# 2. 高斯金字塔:上采样 (放大)
larger_img = cv2.pyrUp(img)

# 3. 拉普拉斯金字塔:构建一层
# 先下采样再上采样,得到一个模糊的大图
up_after_down = cv2.pyrUp(cv2.pyrDown(img))
# 确保尺寸一致后,相减得到拉普拉斯层 (高频细节)
laplacian_layer = img - cv2.resize(up_after_down, (img.shape[1], img.shape[0]))

函数参数详解

cv2.pyrDown(src, dst, dstsize, borderType)

src:输入图像。

dst:输出图像,尺寸默认为 ((src.cols+1)/2, (src.rows+1)/2)

dstsize:可指定输出大小,但需满足特定条件。

borderType:边界填充方式,默认为 cv.BORDER_DEFAULT

cv2.pyrUp(src, dst, dstsize, borderType):参数含义与 pyrDown 类似。

🛠️ 实际应用场景

图像金字塔是许多高级视觉任务的基础,它的核心价值在于提供多尺度信息。

 
 
应用场景 核心价值
图像融合与拼接 在全景图拼接或混合不同曝光的照片时,使用金字塔可以在不同尺度上进行融合,有效消除生硬的拼接缝,让结果更自然。
多尺度目标检测 通过在金字塔的每一层检测目标,可以同时发现图中“远处的小目标”和“近处的大目标”,极大提升检测的准确率和鲁棒性,是Haar级联等经典检测器的基础。
尺度不变特征提取 SIFT(尺度不变特征变换)等经典算法依赖图像金字塔来构建尺度空间,从而在不同大小的图像上检测到稳定、可重复的关键点。
图像增强与去噪 金字塔不同层包含不同频率的信息。可以在顶层(低分辨率)处理轮廓和噪声,在底层(高分辨率)增强纹理细节,实现更精细的图像处理。
图像压缩 金字塔顶层的低分辨率图像数据量极小,可作为压缩的基础。结合能保留细节的拉普拉斯金字塔,能在高压缩比下尽可能保留图像的关键信息。

下面我们通过代码实例来看一下:

1、高斯金字塔

# 高斯金字塔(Gaussian pyramid):用来向下/上采样,主要的图像金字塔,取样不可逆
import cv2
import numpy as np
import matplotlib.pyplot as plt
from opencv_jupyter_ui import cv2_imshow
# from utils import plt_showimg
#导入图片
img = cv2.imread('./images/dog.png')
print(img.shape)
#分辨率减小的操作,下采样
dst = cv2.pyrDown(img)

#分辨率增大的操作,上采样
# dst = cv2.pyrUp(img)

print(dst.shape)
cv2_imshow('img', img)
cv2_imshow('pyrDown', dst)

效果图如下:

2、拉普拉斯金字塔

# 拉普拉斯金字塔是由高斯金字塔构成的,没有专门的函数,拉普拉斯金字塔图像只像图像边缘,它的大部分元素都是0,用于图像压缩.
# 也就是说,拉普拉斯金字塔是通过源图像减去先缩小后再放大的图像的一系列图像构成的。保留的是残差!

# 拉普拉斯金字塔(Laplacianpyramid):用来从金字塔低层图像重建上层未采样图像,在数字图像处理中也即是预测残差,
# 可以对图像进行最大程度的还原,配合高斯金字塔一起使用。
import cv2
import numpy as np
from opencv_jupyter_ui import cv2_imshow
#导入图片
img = cv2.imread('./images/dog.png')
print(img.shape)
#分辨率减小的操作,下采样
dst = cv2.pyrDown(img)
#分辨率增大的操作,上采样
dst = cv2.pyrUp(dst)
# print(dst.shape)
#原图 和高斯金字塔的差就是拉普拉斯金字塔
lap0 = img - dst

dst1 = cv2.pyrDown(dst)
dst1 = cv2.pyrUp(dst1)

#原图 和高斯金字塔的差就是拉普拉斯金字塔
lap1 = dst - dst1

cv2_imshow('img,lap0,lap1', np.hstack((img,lap0,lap1)))

运行效果图如下:


全部评论