图像基础增强:翻转、旋转、缩放、裁剪、平移、颜色抖动、亮度/对比度调整

各位同学,咱们今天聊点实在的。

图像增强,说白了就是给数据「化妆」。你想想看,模型训练时如果只有几千张原图,那它学到的特征就太局限了。我刚开始做图像项目时,总觉得数据不够用,后来才发现——不是数据不够,是增强没做透。

为什么图像增强这么重要?

模型本质上是个「见过世面」的机器。你给它看的图片都是正着拍的、光线均匀的、物体居中的,那它换个角度、换个光线就懵了。增强的目的,就是模拟真实世界中千变万化的场景。

我个人习惯,在数据预处理阶段至少做 3-5 种增强组合。别怕麻烦,这一步省了,后面调参能让你哭出来。

核心原则:增强后的图片不能改变原始语义。比如把猫的图片左右翻转,它还是一只猫;但如果你把猫上下翻转,模型可能就学成「倒挂的猫」了——这在现实场景中很少见。

一、翻转(Flip)

翻转是最简单、最安全的增强方式。分两种:水平翻转和垂直翻转。

  • 水平翻转:左右镜像。适合大多数自然场景,比如风景、物体、人脸(注意:文字、车牌等有方向性的内容慎用)。
  • 垂直翻转:上下颠倒。这个要小心,除非你的应用场景确实有倒置的情况(比如无人机航拍)。
# 水平翻转示例
import cv2
import numpy as np

img = cv2.imread('cat.jpg')
flipped_h = cv2.flip(img, 1)  # 1 表示水平翻转
flipped_v = cv2.flip(img, 0)  # 0 表示垂直翻转

我的经验:做目标检测时,水平翻转一定要同步翻转标注框的坐标。我曾经犯过这个错,训练出来的模型定位全偏了,排查了两天才发现是标注没跟着翻。

二、旋转(Rotation)

旋转能让模型学会「不同角度下的物体长什么样」。但要注意,旋转后图片边缘会出现黑边或空白区域。

  • 小角度旋转(±15°以内):适合大多数场景,信息损失小。
  • 大角度旋转(±45°以上):适合圆形对称物体,比如细胞、卫星图像。
# 旋转示例
(h, w) = img.shape[:2]
center = (w // 2, h // 2)
M = cv2.getRotationMatrix2D(center, 30, 1.0)  # 旋转30度
rotated = cv2.warpAffine(img, M, (w, h))

注意:旋转后产生的黑边,可以用填充模式处理(比如复制边缘像素或填充纯色)。我一般用 cv2.BORDER_REFLECT,效果比较自然。

三、缩放(Scaling)

缩放模拟的是「物体离镜头远近不同」的情况。分两种:

  • 等比例缩放:保持宽高比,不会变形。
  • 非等比例缩放:会拉伸图像,一般不建议用,除非你的应用场景本身就有畸变。
# 缩放示例
resized = cv2.resize(img, None, fx=0.8, fy=0.8, interpolation=cv2.INTER_LINEAR)

避坑指南:缩放后别忘了检查图像尺寸是否还是模型输入要求的大小。我见过有人缩放后直接喂给模型,结果尺寸不匹配,报错报了一下午。

四、裁剪(Cropping)

裁剪是「局部特写」的模拟。随机裁剪一块区域,然后缩放到原图大小。

  • 中心裁剪:固定裁剪中间区域,适合主体居中的图片。
  • 随机裁剪:随机位置裁剪,能大幅增加数据多样性。
# 随机裁剪示例
h, w = img.shape[:2]
x = np.random.randint(0, w - 200)
y = np.random.randint(0, h - 200)
cropped = img[y:y+200, x:x+200]
cropped = cv2.resize(cropped, (w, h))  # 缩放到原图大小

关键点:裁剪时如果目标物体被切掉一部分,模型可能学不到完整特征。我建议裁剪比例控制在原图的 60%-90% 之间。

五、平移(Translation)

平移就是让物体在画面中「走动」。模型通过平移增强,能学会「物体不在画面中心时也能识别」。

# 平移示例
M = np.float32([[1, 0, 50], [0, 1, 30]])  # 向右平移50像素,向下平移30像素
translated = cv2.warpAffine(img, M, (w, h))

我的习惯:平移量一般不超过图像尺寸的 20%,否则物体可能跑出画面,那就没意义了。

六、颜色抖动(Color Jittering)

颜色抖动是调整图像的色调、饱和度、明度等。说白了,就是让模型适应不同光照和色彩环境。

  • 色调调整:改变颜色的基调,比如偏黄、偏蓝。
  • 饱和度调整:让颜色更鲜艳或更灰暗。
  • 明度调整:整体变亮或变暗。
# 颜色抖动示例(使用HSV空间)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
hsv[:,:,0] = (hsv[:,:,0] + 10) % 180  # 色调偏移
hsv[:,:,1] = np.clip(hsv[:,:,1] * 1.2, 0, 255)  # 饱和度增强
hsv[:,:,2] = np.clip(hsv[:,:,2] * 0.9, 0, 255)  # 明度降低
jittered = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)

注意:颜色抖动幅度不要太大。我曾经把一张蓝天白云的图调成了紫色,模型直接学歪了。建议色调偏移不超过 ±20,饱和度/明度变化不超过 30%。

七、亮度/对比度调整

这两个参数是图像增强的「基本功」。亮度控制整体明暗,对比度控制明暗差异程度。

# 亮度和对比度调整
alpha = 1.2  # 对比度控制(1.0 为原始)
beta = 30    # 亮度控制(0 为原始)
adjusted = cv2.convertScaleAbs(img, alpha=alpha, beta=beta)

经验之谈:做夜间场景识别时,我会把亮度调低、对比度调高,模拟真实夜视效果。白天场景则相反。这个组合拳打好了,模型泛化能力能提升一大截。

知识体系总览

下面这张图,是我自己梳理的图像基础增强知识结构。你可以把它当作「增强工具箱」的目录。

图像基础增强 几何变换 翻转 旋转 缩放 裁剪 平移 颜色变换 颜色抖动 亮度调整 对比度调整 目标:提升模型泛化能力,防止过拟合 注意:几何变换需同步调整标注信息 颜色变换幅度不宜过大,避免改变语义

实战建议

说了这么多,到底怎么用?我一般按这个顺序来:

  1. 先做几何变换:翻转、旋转、缩放、裁剪、平移。这些改变的是物体位置和姿态。
  2. 再做颜色变换:颜色抖动、亮度/对比度调整。这些改变的是环境光照。
  3. 组合使用:比如「水平翻转 + 随机裁剪 + 亮度调整」,效果比单一增强好得多。

最后提醒一句:增强不是越多越好。我见过有人一张图增强出 100 张,结果模型训练时间翻了三倍,精度反而没提升。适可而止,根据你的数据量和任务复杂度来定。


公众号:蓝海资料掘金营,微信deep3321