3. 图像饱和度调节

任务说明

本案例实现图像饱和度随机调节,用于数据增强场景:在训练前对输入图像施加随机的饱和度扰动,使模型对不同色彩环境更具鲁棒性。核心要求是:每次调用产生不同的饱和度缩放因子,且处理后的图像保持与原图相同的尺寸与数据类型。

实现方案

使用OpenCV的HSV色彩空间转换完成饱和度调整。将图像从BGR转为HSV后,对S通道乘以随机缩放因子,再转回BGR。缩放因子从[0.5, 1.5]区间均匀采样,因子小于1降低饱和度,大于1增强饱和度。实现采用批量处理接口,便于直接嵌入训练数据流水线。

完整代码

import cv2
import numpy as np

def random_saturation_adjust(image, factor_range=(0.5, 1.5)):
    """
    随机调整图像饱和度
    Args:
        image: BGR格式图像,uint8类型,HWC布局
        factor_range: (min_factor, max_factor),饱和度缩放范围
    Returns:
        饱和度调整后的BGR图像,与原图同尺寸同类型
    """
    # 随机采样饱和度缩放因子
    factor = np.random.uniform(factor_range[0], factor_range[1])
    
    # BGR -> HSV
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV).astype(np.float32)
    
    # 对S通道应用缩放因子,并裁剪到合法范围[0, 255]
    hsv[:, :, 1] = np.clip(hsv[:, :, 1] * factor, 0, 255)
    
    # HSV -> BGR,恢复uint8类型
    adjusted = cv2.cvtColor(hsv.astype(np.uint8), cv2.COLOR_HSV2BGR)
    return adjusted

def batch_augment(images, factor_range=(0.5, 1.5)):
    """
    对一批图像逐张应用随机饱和度调整
    Args:
        images: BGR图像数组,shape为(N, H, W, 3),uint8类型
        factor_range: 饱和度缩放范围
    Returns:
        增强后的图像数组,shape与输入一致
    """
    augmented = np.zeros_like(images)
    for i in range(images.shape[0]):
        augmented[i] = random_saturation_adjust(images[i], factor_range)
    return augmented

if __name__ == "__main__":
    # 生成一张测试图像(纯色块,便于观察饱和度变化)
    test_img = np.zeros((200, 200, 3), dtype=np.uint8)
    test_img[:, :100] = (255, 0, 0)    # 左半:纯蓝
    test_img[:, 100:] = (0, 255, 0)    # 右半:纯绿
    
    # 固定随机种子,保证可复现
    np.random.seed(42)
    
    # 执行两次增强,展示随机性
    out1 = random_saturation_adjust(test_img)
    out2 = random_saturation_adjust(test_img)
    
    # 验证输出形状与类型
    assert out1.shape == test_img.shape, "输出尺寸不匹配"
    assert out1.dtype == np.uint8, "输出类型错误"
    
    # 计算饱和度均值,验证确实发生变化
    hsv_orig = cv2.cvtColor(test_img, cv2.COLOR_BGR2HSV)
    hsv_out1 = cv2.cvtColor(out1, cv2.COLOR_BGR2HSV)
    hsv_out2 = cv2.cvtColor(out2, cv2.COLOR_BGR2HSV)
    
    print(f"原图S通道均值: {hsv_orig[:,:,1].mean():.1f}")
    print(f"第一次增强S均值: {hsv_out1[:,:,1].mean():.1f}")
    print(f"第二次增强S均值: {hsv_out2[:,:,1].mean():.1f}")
    print("两次结果不同:", not np.array_equal(out1, out2))
    print("形状与类型验证通过")

运行方式

# 安装依赖(如已安装可跳过)
pip install opencv-python numpy

# 运行验证脚本
python saturation_augment.py

验证方法与通过标准

  • 形状与类型:输出图像与输入图像具有完全相同的height、width和通道数,且保持uint8类型——代码中assert语句自动检查。
  • 随机性:连续两次调用同一输入图像,输出结果不同(因每次采样不同缩放因子)。
  • 饱和度变化:程序打印原图与增强后图像的S通道均值,观察数值差异即可确认饱和度被修改。由于随机因子范围在[0.5, 1.5],S均值可能增大或减小。
  • 边界安全:所有像素值经np.clip限制在[0,255],不会出现溢出或异常色斑。

若打印的S均值与原图不同、两次输出不一致且无报错,则判定增强功能正常。实际训练中可将batch_augment嵌入数据加载流程,对每个batch调用即可。