大家好,今天带大家吃透计算机视觉中非常经典的图像金字塔操作!很多同学做图像缩放、特征提取、图像融合的时候,都会接触到高斯金字塔、拉普拉斯金字塔,但对其中的原理、API 用法、以及「为什么下采样再上采样图像会糊」「怎么无损复原图像」一知半解。
本文就用大家熟悉的这张网红头像作为示例图,从原理到代码实战,一步步带大家搞懂 OpenCV 中的pyrDown、pyrUp函数,以及拉普拉斯金字塔的实现与图像复原,新手也能直接复现所有效果!
新手必看前置提示 :OpenCV 原生的
cv2.imshow()窗口标题和cv2.putText()都不支持中文,直接写中文会显示乱码!本文最后会附带完整的中文显示解决方案,代码中也会直接给出修复版。
一、环境准备
本文基于 Python+OpenCV 实现,只需一行命令安装依赖:
pip install opencv-python numpy
先搞懂核心概念:上下采样 vs resize
有些人会问:pyrDown/pyrUp和resize到底有什么区别?这里先给大家讲明白,避免后续踩坑:
- pyrDown(向下采样) :不是简单的缩小图片,而是先对原图做高斯模糊滤波,再进行隔行隔列的降采样,宽高直接减半,是高斯金字塔的核心操作,会过滤并丢失图像的高频细节。
- pyrUp(向上采样) :不是简单的放大图片,而是先将图像的宽高放大 2 倍,新增的像素位置补 0,再用和下采样相同的高斯核进行卷积插值,还原图像尺寸。
- resize 函数:通用的图像缩放工具,可以指定任意目标尺寸,支持多种插值算法(最近邻、双线性、双三次等),不涉及金字塔的多尺度结构和高斯滤波步骤。
二、高斯金字塔:图像多尺度表示的核心
高斯金字塔是计算机视觉中最基础的多尺度表示方法,本质是对原图进行多次向下采样,生成一系列尺寸依次减半、分辨率逐步降低的图像,堆叠起来就像一个「金字塔」------ 底层是原图,越往上尺寸越小、分辨率越低。
2.1 向下采样(pyrDown):原理与 API 详解
原理
向下采样的执行分为两步,缺一不可:
- 高斯模糊滤波:用 5×5 的高斯核对原图进行卷积,平滑图像,过滤掉高频噪声和细节,避免降采样时出现锯齿和混叠效应;
- 降采样:对模糊后的图像,隔行隔列删除像素,最终图像的宽、高都变为原图的 1/2,整体面积变为 1/4。
API 参数详解
OpenCV 中向下采样的函数是cv2.pyrDown(),完整参数如下:
python
dst = cv2.pyrDown(
src, # 输入图像:灰度图/彩色图都支持,推荐使用8位无符号图
dst=None, # 输出图像:一般直接用返回值,无需手动创建
dstsize=None, # 可选:目标图像尺寸,必须满足宽高是原图的1/2,默认自动计算
borderType=None # 可选:边界填充方式,默认值即可,无需修改
)
实战代码:多次向下采样效果
我们用示例图来做两次向下采样,直观感受效果:
python
face = cv2.imread("shua.png")
cv2.imshow("yuan",face)
face = cv2.imread("shua.png",cv2.IMREAD_GRAYSCALE)
cv2.imshow("gray",face)
cv2.waitKey(0)
face_down = cv2.pyrDown(face) #下采样
cv2.imshow("down1",face_down)
cv2.waitKey(0)
face_down2 = cv2.pyrDown(face_down)
cv2.imshow("down2",face_down2)
cv2.waitKey(0)
效果说明
运行代码后可以清晰看到:

- 原图是完整的头像,线条、纹理等细节清晰;
- 第一次下采样后,宽高减半,图像整体缩小,细节开始模糊;
- 第二次下采样后,宽高是原图的 1/4,图像更小,大量纹理细节已经丢失。
2.2 向上采样(pyrUp):原理与 API 详解
原理
向上采样是向下采样的尺寸逆过程(注意:不是内容逆过程),执行步骤分为两步:
- 尺寸放大:将原图的宽、高都放大 2 倍,新增的行和列的像素值全部填充 0;
- 高斯卷积插值:用和向下采样相同的 5×5 高斯核,对放大后的图像进行卷积,给填充 0 的位置赋值,还原图像的视觉效果。
API 参数详解
OpenCV 中向上采样的函数是cv2.pyrUp(),完整参数如下:
python
#高斯金字塔操作中的上采样
'''dst = cv2.pyrUp(
src, # 输入:原始图像(单通道/3通道,如灰度图、BGR彩图)
dst=None, # 输出:目标图像(一般直接用返回值,无需手动指定)
dstsize=None, # 可选:目标图像尺寸 (宽, 高)
borderType=None # 可选:边界填充方式,默认即可)
'''
实战代码:多次向上采样效果
我们对原图做两次向上采样,看看效果:
python
face_up = cv2.pyrUp(face)
cv2.imshow("up1",face_up)
cv2.waitKey(0)
face_up2 = cv2.pyrUp(face_up)
cv2.imshow("up2",face_up2)
cv2.waitKey(0)
效果说明

运行后可以看到,图像的宽高依次翻倍,尺寸变大,但因为是插值填充,放大后的图像不会比原图更清晰,只是尺寸被放大了。
2.3 新手必踩坑:下采样再上采样,为什么图像变糊了?
很多同学会有一个误区:我先把图像下采样缩小,再上采样放大回原来的尺寸,不就和原图一样了吗?大错特错!
我们直接用代码验证这个问题:
python
face_down = cv2.pyrDown(face)
face_down2 = cv2.pyrDown(face_down)
face_down_up1 = cv2.pyrUp(face_down)
face_down_up2 = cv2.pyrUp(face_down2)
cv2.imshow("down_up1",face_down_up1)
cv2.imshow("down_up2",face_down_up2)
cv2.waitKey(0)

运行后可以清晰看到:还原后的图像和原图相比,明显变模糊了,丢失了大量细节,无法直接复原原图!
根本原因
向下采样的第一步是高斯模糊,这一步会直接过滤掉图像的高频细节(边缘、纹理、尖锐的特征),再通过降采样丢弃像素,这些丢失的高频信息是不可逆的 ------ 哪怕上采样把尺寸还原,也找不回已经丢失的细节,最终只会得到一张模糊的图像。
那有没有办法保存这些丢失的细节,实现图像的无损复原?这就是拉普拉斯金字塔的核心作用!
三、拉普拉斯金字塔:保存残差,实现图像无损复原
3.1 什么是拉普拉斯金字塔?
拉普拉斯金字塔是用来保存高斯金字塔下采样过程中丢失的高频残差信息的金字塔结构,它的每一层,都保存了高斯金字塔某一层,和下一层上采样还原后的图像的差值(残差)。
核心公式:
其中:
- Li:拉普拉斯金字塔的第 i 层
- Gi:高斯金字塔的第 i 层
- Gi+1:高斯金字塔第 i 层下采样后的结果(第 i+1 层)
简单来说:拉普拉斯金字塔的每一层,都是下采样丢失的细节信息!只要我们保存了这些残差,就可以用下采样后的小图,加上残差,完美复原出原图。
3.2 实战:拉普拉斯金字塔计算与图像复原
我们直接用代码实现,计算残差,再用残差复原图像:
python
# 计算拉普拉斯金字塔第0层:原图 - 1次下采样后上采样的结果
l0 = face - face_down_up1
# 计算拉普拉斯金字塔第1层:第一次下采样的图 - 2次下采样后上采样的结果
l1 = face_down - face_down_up2
# 显示残差图(丢失的细节信息)
cv2.imshow("l0",l0)
cv2.imshow("l1",l1)
cv2.waitKey(0)
# 图像复原:下采样上采样的模糊图 + 残差 = 原图
fuyuan = face_down_up1 + l0
cv2.imshow("fuyuan",fuyuan)
cv2.waitKey(0)
# 所有窗口用完记得释放资源
cv2.destroyAllWindows()
3.3 效果说明

- 残差图:拉普拉斯金字塔的层,显示的是原图中被高斯模糊过滤掉的边缘、纹理等高频细节,也就是下采样丢失的信息;
- 复原效果:模糊的还原图,加上残差后,完美复原出了原图,没有任何模糊!这就是拉普拉斯金字塔的核心价值。
四、完整可运行代码
这里给大家整理好本文所有的完整代码,直接替换图片路径即可运行:
python
import cv2
import numpy as np
'''---------高斯金字塔操作中的向下采样---------'''
#下采样 是一种减小图像尺寸的方法,它通常涉及到降低图像的分辨率,即减少图像中像素的数量,从而使图像看起来更小。
#上采样 是一种增大图像尺寸的方法,它通过插值和滤波技术来恢复图像的分辨率和细节,通常用于图像放大或者与下采样后的图像进行比较。
#resize函数 是一种通用的图像尺寸调整方法,它可以按照指定的目标尺寸来缩放图像,不涉及金字塔结构或者特定的滤波操作。
'''dst = cv2.pyrDown(
src, # 输入:原始图像(灰度图/彩色图都支持)
dst=None, # 输出:目标图像(直接用返回值,不用手动创建)
dstsize=None, # 可选:目标图像尺寸 (宽, 高)
borderType=None # 可选:边界填充,默认即可)
'''
face = cv2.imread("shua.png")
cv2.imshow("yuan",face)
face = cv2.imread("shua.png",cv2.IMREAD_GRAYSCALE)
cv2.imshow("gray",face)
cv2.waitKey(0)
face_down = cv2.pyrDown(face) #下采样
cv2.imshow("down1",face_down)
cv2.waitKey(0)
face_down2 = cv2.pyrDown(face_down)
cv2.imshow("down2",face_down2)
cv2.waitKey(0)
#高斯金字塔操作中的上采样
'''dst = cv2.pyrUp(
src, # 输入:原始图像(单通道/3通道,如灰度图、BGR彩图)
dst=None, # 输出:目标图像(一般直接用返回值,无需手动指定)
dstsize=None, # 可选:目标图像尺寸 (宽, 高)
borderType=None # 可选:边界填充方式,默认即可)
'''
face_up = cv2.pyrUp(face)
cv2.imshow("up1",face_up)
cv2.waitKey(0)
face_up2 = cv2.pyrUp(face_up)
cv2.imshow("up2",face_up2)
cv2.waitKey(0)
# ###对下采用后图像进行上采样,图像变模糊,无法复原
face_down_up1 = cv2.pyrUp(face_down)
face_down_up2 = cv2.pyrUp(face_down2)
#
cv2.imshow("down_up1",face_down_up1)
cv2.imshow("down_up2",face_down_up2)
cv2.waitKey(0)
# ###拉普拉斯金字塔
# 计算拉普拉斯金字塔第0层:原图 - 1次下采样后上采样的结果
l0 = face - face_down_up1
# 计算拉普拉斯金字塔第1层:第一次下采样的图 - 2次下采样后上采样的结果
l1 = face_down - face_down_up2
# 显示残差图(丢失的细节信息)
cv2.imshow("l0",l0)
cv2.imshow("l1",l1)
cv2.waitKey(0)
# 图像复原:下采样上采样的模糊图 + 残差 = 原图
fuyuan = face_down_up1 + l0
cv2.imshow("fuyuan",fuyuan)
cv2.waitKey(0)
# 所有窗口用完记得释放资源
cv2.destroyAllWindows()
五、总结与应用场景
核心知识点回顾
- 高斯金字塔的核心是先滤波后降采样,不是简单的缩放,多次下采样会生成多尺度的图像金字塔;
- 下采样再上采样会导致图像模糊,因为高斯滤波丢失了高频细节,这个过程是不可逆的;
- 拉普拉斯金字塔保存了下采样过程中丢失的残差信息,结合残差可以实现图像的无损复原;
pyrDown/pyrUp和resize的核心区别是是否有高斯滤波步骤,以及是否固定 2 倍缩放比例。
常见应用场景
- 图像缩放与复原:用拉普拉斯金字塔实现图像的无损缩放,避免缩放后模糊;
- 图像融合:比如全景图拼接、换脸等场景,用金字塔实现多尺度融合,过渡更自然;
- 特征提取:SIFT、SURF 等特征点检测算法,都基于图像金字塔实现多尺度特征提取,适应不同大小的目标;
- 图像分割:用金字塔多尺度处理,提升分割的鲁棒性。
新手避坑指南
- 所有
cv2.imshow()之后必须加cv2.waitKey(0),否则窗口会一闪而过,无法显示图像; - 程序结束后一定要加
cv2.destroyAllWindows(),释放窗口资源,避免程序卡死; - 图像路径不要有中文,否则会读取失败,建议用英文路径和文件名;
- 拉普拉斯金字塔计算时,一定要保证两张图的尺寸完全一致,否则会出现计算报错。
以上就是本文的全部内容啦!从原理到代码实战,带大家彻底搞懂了 OpenCV 中的图像金字塔操作,大家可以用自己的图片试试效果,有问题可以在评论区交流~