图像处理入门012 | 图像裁剪与缩放:resize 与 ROI 操作

系列:《图像处理算法入门 144 期》· 模块二:数字图像基础操作

标签:OpenCV / Pillow / resize / ROI / 插值 / Letterbox / 入门


一、前言

上一期(011)我们聊了图像的"身份证"------shape / dtype / size,搞清楚了图像在内存里到底是什么样子。本期进入 M02 基础操作的第四期 ,主题聚焦两个最高频的需求:缩放(resize)裁剪(ROI)

无论是给深度学习模型准备输入数据、生成缩略图、还是做图像增强预处理,cv2.resize 都是绕不开的 API。但你真的用对了吗?

场景 推荐插值 理由
模型推理输入预处理 INTER_LINEAR / INTER_AREA(缩小) 速度快,效果稳;YOLO/ResNet 默认
高质量图像放大 INTER_CUBIC / INTER_LANCZOS4 边缘更平滑,保留细节
实时视频缩放 INTER_NEAREST 极限速度优先
数据增强随机裁剪 任意,配合 ROI 切片 内容不变,关注几何变换

本期会带你:

  1. 4 种插值 做 resize 对比
  2. PSNR + SSIM 客观评测差异
  3. 学会两种 ROI 裁剪 写法(OpenCV 切片 vs Pillow crop)
  4. 封装一个生产级的 智能缩放工具(Letterbox)

二、resize 的四种插值方法

2.1 插值原理速览

缩放的本质是用原图若干像素去"估"出新图的像素值。插值方法决定了估计的精度与速度

插值方法 OpenCV 常量 复杂度 边缘特征 典型用途
最近邻 INTER_NEAREST O(1) 锯齿明显 实时视频、像素画
双线性 INTER_LINEAR O(4) 稍模糊 通用(OpenCV 默认)
像素区域(缩小专用) INTER_AREA - 最佳 缩小操作
双三次 INTER_CUBIC O(16) 平滑锐利 高质量放大
兰索斯 4×4 INTER_LANCZOS4 O(64) 综合最优 专业级放大

2.2 一行代码对比

python 复制代码
import cv2

img = cv2.imread("photo.jpg")  # 原始 HxW
methods = {
    "最近邻": cv2.INTER_NEAREST,
    "双线性": cv2.INTER_LINEAR,
    "双三次": cv2.INTER_CUBIC,
    "兰索斯": cv2.INTER_LANCZOS4,
}
for name, flag in methods.items():
    resized = cv2.resize(img, (new_w, new_h), interpolation=flag)

OpenCV 的经验法则:

  • 缩小cv2.INTER_AREA(避免摩尔纹)
  • 放大cv2.INTER_CUBIC / cv2.INTER_LANCZOS4
  • 通用cv2.INTER_LINEAR

三、客观质量评估:PSNR 与 SSIM

光看主观图不够,我们用 PSNR(峰值信噪比)SSIM(结构相似性) 量化对比:

  • PSNR 越大越好(单位 dB,>30dB 通常视为难以察觉损失)
  • SSIM ∈ 0, 1,越接近 1 越好

对同一张测试图(540×360→216×144→还原到 540×360)做 4 种插值,实测得分如下:

插值方法 PSNR (dB) SSIM
INTER_NEAREST (最近邻) 16.41 0.9737
INTER_LINEAR (双线性) 20.10 0.9886
INTER_CUBIC (双三次) 20.08 0.9884
INTER_LANCZOS4 (兰索斯) 20.04 0.9881

结论 :在这张测试图上双线性反而是综合最优------双三次与兰索斯因轻微振铃(ringing)拉低了得分。最近邻分数明显偏低,锯齿丢失了边缘结构信息。

这告诉我们:没有"最好的插值",只有"最适合场景的插值"。对于自然风景照、人像,兰索斯更优;对于 UI 截图、几何线条,最近邻更合适。


四、ROI 裁剪:OpenCV vs Pillow 两种写法

ROI(Region of Interest,感兴趣区域)是图像处理的"基本手"------裁框、人脸定位、目标检测标注都靠它。

4.1 OpenCV 写法(NumPy 切片)

OpenCV 图像就是 np.ndarray,最直接的裁法就是切片:

python 复制代码
img = cv2.imread("photo.jpg")            # shape: (H, W, C)  ← 注意顺序!
roi = img[y1:y2, x1:x2]                  # 行(高)维度先,列(宽)维度后

坑点img.shape(H, W, C),但是 cv2.resize(img, (W, H)) 的参数是 (W, H),很多初学者都会搞反!

4.2 Pillow 写法(Image.crop)

Pillow 把图像当对象,坐标更"自然":

python 复制代码
from PIL import Image
pil_img = Image.open("photo.jpg")       # size: (W, H)  ← 也是 W 先!
roi = pil_img.crop((left, upper, right, lower))   # box 是 (x1, y1, x2, y2)

两种写法结果完全一致,只是风格差异:

核心记忆点

  • OpenCV / NumPy → 先高度 H(行),后宽度 W(列)
  • Pillow / cv2.resize → 先宽度 W(列),后高度 H(行)

五、生产级工具:智能缩放(Letterbox)

5.1 为什么需要 Letterbox?

直接 cv2.resize强制拉伸------把一张竖向人像压缩成正方形,脸会变形,这在给深度学习模型准备输入时是致命的:

复制代码
原始 540×360  →  直接 resize 到 224×224  →  拉伸变形 ❌
原始 540×360  →  Letterbox 到 224×224   →  等比缩放 + 灰边 ✅

Letterbox(letterboxing,"信箱模式")的策略:

  1. 计算缩放比例 = min(target_w/src_w, target_h/src_h),取较小者保证完整放入
  2. 按比例缩放 → 居中放置 → 四周填中性灰 (114, 114, 114)(YOLO 默认值)

5.2 完整实现

python 复制代码
def smart_resize_keep_ratio(
    img, target_w, target_h, pad_color=(114, 114, 114)
):
    h, w = img.shape[:2]
    scale = min(target_w / w, target_h / h)
    new_w, new_h = int(w * scale), int(h * scale)

    # 1) 等比缩放
    resized = cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_LANCZOS4)

    # 2) 创建目标画布并居中放置
    canvas = np.full((target_h, target_w, 3), pad_color, dtype=np.uint8)
    x_off = (target_w - new_w) // 2
    y_off = (target_h - new_h) // 2
    canvas[y_off:y_off + new_h, x_off:x_off + new_w] = resized

    return canvas, scale, (x_off, y_off, new_w, new_h)

5.3 四种缩放策略对比

什么时候用哪种策略?

场景 推荐策略 备注
目标检测模型输入 Letterbox YOLOv5/v8 默认
图像分类模型输入 Letterbox 或中心裁剪 ResNet/VGG
网页缩略图 Letterbox 不变形即可
头像/封面裁剪 中心裁剪 抛弃背景信息
打印/印刷品 直接拉伸到目标尺寸 高分辨率源图

5.4 一键输出深度学习输入尺寸

下面这行代码就能把任意尺寸图缩到 224×224(ResNet 经典输入):

python 复制代码
lb_224, scale, box = smart_resize_keep_ratio(img, 224, 224)

输出效果(540×360→224×224,scale=0.4148,等比缩放居中):


六、完整代码

完整脚本已保存到 code/012_resize_crop.py,运行后会自动在 code/output/ 下生成 5 张图:

复制代码
code/012_resize_crop.py    # 本期代码
code/output/012_source.png              # 测试原图
code/output/012_interpolation_quality.png  # PSNR+SSIM 对比
code/output/012_roi_crop_compare.png    # OpenCV vs Pillow ROI
code/output/012_smart_resize_compare.png # 4 种缩放策略
code/output/012_letterbox_224.png       # 深度学习输入样例

运行方式:

bash 复制代码
"C:/Users/kazen/.workbuddy/binaries/python/envs/cv_env/Scripts/python.exe" code/012_resize_crop.py

七、常见问题 FAQ

Q1:缩放后颜色变了(偏色),怎么办?

检查 dtype:若图像是 float32,插值可能产生负值或 >1 的值,务必 np.clip(..., 0, 255) 后再转回 uint8

Q2:Letterbox 的填充色为什么是 (114,114,114)?

这是 YOLOv5/v8 的默认值,对应 0.45 灰度。对于亮度自适应模型(如 SAM),可以改为 (0,0,0),或用图像均值作为填充色。

Q3:放大到很大的尺寸(10 倍+)出现明显模糊?

这是插值的"硬天花板"。需要上深度学习方案:Real-ESRGAN / Topaz Gigapixel AI / SD 放大。详细对比将在 M13 深度学习模块展开。

Q4:批量缩放一堆图,怎么写最简洁?

pathlib.Path.glob('*.jpg') + tqdm 加进度条,或者用 Image.open + PIL.ImageOps.fit()(带自动裁剪)。具体代码我们会在 017 期「批量处理 pipeline」详细讲。

Q5:Pillow 的 thumbnail()resize() 有什么区别?

thumbnail()原地操作 ,只缩小不放大;resize() 返回新图,能双向缩放。


八、课后练习

  1. 基础练习 :用 OpenCV 写一个 pad_to_square(img, fill_color),把任意矩形图补成正方形。
  2. 进阶练习 :扩展 smart_resize_keep_ratio,支持"右对齐 / 左对齐 / 底部对齐"等非居中模式(YOLOv5-Aug 增强版本)。
  3. 挑战练习 :实现一个 resize_and_cover(类似 CSS object-fit: cover),先等比缩放到完全覆盖目标框,再中心裁剪,对比 letterbox 的视觉效果差异。

九、本期小结 & 下期预告

维度 内容
核心 API cv2.resize()cv2.INTER_*PIL.Image.crop()
核心策略 Letterbox(保比例+灰边)、中心裁剪(切边)
评估指标 PSNR、SSIM
实战工具 smart_resize_keep_ratio 智能缩放
下一步 013 期:图像旋转与翻转:几何重采样详解,讲任意角度旋转 + 自适应画布

本文为《图像处理算法入门 144 期》系列第 012 期,面向入门者强调实操性,所有代码均经过本地实测运行。如有疏漏,欢迎评论区指正。

配套仓库:https://github.com/yourname/image-processing-144(示例代码,无实际依赖)

推荐产品(本期主题:缩放与裁剪)

类别 代表产品 用例
移动端 稿定设计(图片裁剪/拼图)、剪映(视频帧裁剪)、醒图(智能裁切主体) 日常裁图、构图优化
专业级 Figma(设计稿自适应框)、Adobe Photoshop(裁剪工具+内容识别缩放)、Capture One(高保真批量缩放) 设计交付、商业出片
相关推荐
clorinda4 小时前
OpenCV图像增强基础——图像金字塔、直方图与特征提取
人工智能·opencv·计算机视觉
zx_741484816 小时前
【计算机视觉入门】基于 OpenCV 的银行卡号识别综合案例
人工智能·opencv·计算机视觉
派大_星8 小时前
OpenCV发票图像处理:轮廓检测、透视变换与图像预处理
人工智能·opencv·计算机视觉
闻道且行之21 小时前
图片处理助手|泊松融合原理 + C++ 工程实现,seamlessClone 三模式一次讲透
数据库·c++·人工智能·opencv
zmzb01031 天前
Python课后习题训练记录Day194
python·opencv·计算机视觉
AI的探索之旅1 天前
图像格式与转换一文讲透:相机 / OpenCV / Qt
数码相机·qt·opencv
uncle_ll1 天前
数字人JoyVASA 实战记录
图像处理·数字人·语音合成
欧特克_Glodon1 天前
OpenCV计算机视觉开发入门与实践<十四>:基础几何图形绘制
人工智能·opencv·计算机视觉
PhotonixBay1 天前
从粗糙度到三维形貌:激光共聚焦显微镜实现微米级表面分析
图像处理·人工智能·测试工具·算法