1. 构建最小图像预处理流水线

构建最小图像预处理流水线 学习卡片

任务说明

本案例构建一个最小可复用的图像预处理流水线,将任意输入图像转换为后续神经网络模型所需的标准张量输入。流水线包含三个核心步骤:缩放(保持宽高比的resize)、中心裁剪(crop至目标尺寸)、归一化(像素值从[0,255]映射到[0,1]并标准化)。输出为形状为(1, 3, H, W)的浮点张量,适配PyTorch模型的默认输入格式(NCHW)。

实现方案

使用OpenCV读取图像(BGR格式),转换为RGB后依次执行缩放、中心裁剪和归一化。归一化采用两步:先将像素值除以255映射到[0,1],再使用ImageNet数据集的均值与标准差进行标准化。代码封装为单一函数preprocess_image(),输入为图像文件路径,输出为可直接送入模型的张量。

读取图像 BGR → RGB 缩放 保持宽高比 短边=256 中心裁剪 224 × 224 归一化 /255 → 标准化 张量 输入: 任意尺寸图像 输出: (1,3,224,224) float32 INTER_AREA 中心区域 mean=[0.485,0.456,0.406] std=[0.229,0.224,0.225]

代码实现


import cv2
import numpy as np
import torch

def preprocess_image(image_path, target_size=224, resize_size=256):
    """
    图像预处理流水线:读取 → 缩放 → 中心裁剪 → 归一化
    
    Args:
        image_path: 输入图像文件路径
        target_size: 最终输出尺寸(正方形边长)
        resize_size: 缩放阶段的短边长度
    
    Returns:
        torch.Tensor: 形状为 (1, 3, target_size, target_size) 的浮点张量
    """
    # 1. 读取图像并转换颜色空间
    img = cv2.imread(image_path)
    if img is None:
        raise FileNotFoundError(f"无法读取图像: {image_path}")
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    
    # 2. 缩放:保持宽高比,短边缩放到 resize_size
    h, w = img.shape[:2]
    scale = resize_size / min(h, w)
    new_h, new_w = int(round(h * scale)), int(round(w * scale))
    img = cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_AREA)
    
    # 3. 中心裁剪:从中心裁出 target_size × target_size 区域
    h, w = img.shape[:2]
    start_y = (h - target_size) // 2
    start_x = (w - target_size) // 2
    img = img[start_y:start_y + target_size, start_x:start_x + target_size]
    
    # 4. 归一化:像素值映射到 [0,1] 后标准化
    img = img.astype(np.float32) / 255.0
    
    # ImageNet 标准化参数
    mean = np.array([0.485, 0.456, 0.406], dtype=np.float32)
    std = np.array([0.229, 0.224, 0.225], dtype=np.float32)
    img = (img - mean) / std
    
    # 转换为 PyTorch 张量并添加 batch 维度
    # 从 HWC 转为 CHW
    tensor = torch.from_numpy(img).permute(2, 0, 1)
    tensor = tensor.unsqueeze(0)  # 添加 batch 维度
    
    return tensor

# 使用示例
if __name__ == "__main__":
    # 输入图像路径(请替换为实际存在的图像文件)
    input_image = "sample.jpg"
    
    # 执行预处理
    output_tensor = preprocess_image(input_image)
    
    # 验证输出形状
    print(f"输出张量形状: {output_tensor.shape}")
    print(f"数据类型: {output_tensor.dtype}")
    print(f"像素值范围: [{output_tensor.min().item():.3f}, {output_tensor.max().item():.3f}]")

落地与验证

依赖安装:需要opencv-python、numpy、torch。使用pip install opencv-python numpy torch安装。

运行方式:将代码保存为preprocess.py,准备一张任意尺寸的sample.jpg图像放在同目录,执行python preprocess.py。

验证方法:观察程序输出,满足以下条件即判定通过:

  • 输出张量形状为torch.Size([1, 3, 224, 224]);
  • 数据类型为torch.float32;
  • 像素值范围大致在[-2.5, 2.5]区间内(标准化后典型范围)。

预期输出示例:对于一张常规自然图像,输出形状为torch.Size([1, 3, 224, 224]),数据类型为torch.float32,像素值范围约为[-2.117, 2.640](具体数值取决于输入图像内容,但必然落在标准化后的合理区间内)。