当前位置: 首页 > news >正文

深度学习图像预处理可视化:拆解Compose操作的全过程

深度学习图像预处理可视化:拆解Compose操作的全过程

背景需求
在深度学习图像处理中,我们经常使用torchvision.transforms.Composetimmcreate_transform将多个预处理步骤组合成一个流水线。但在实际调试中,开发者常会遇到以下问题:

  • 无法直观看到每个变换步骤对图像的具体影响
  • 归一化(Normalize)后的张量难以直接可视化
  • 随机增强(如翻转、裁剪)导致结果不可复现时难以定位问题

本文目标
通过代码实现以下功能:

  1. 逐步拆解预处理流水线,记录每个中间步骤的输出
  2. 自动可视化所有变换结果(包括PIL图像和归一化后的张量)
  3. 智能布局子图排列,避免空白区域过多
  4. 动态反归一化处理,还原可读性图像

技术实现亮点

# 关键代码段解析
cols = math.ceil(math.sqrt(total_steps))  # 根据步骤数量动态计算列数
rows = math.ceil(total_steps / cols)      # 计算所需行数

# 反归一化处理(以Normalize步骤为例)
if name == "Normalize":
    tmp = img_step.permute(1,2,0).numpy() * std + mean  # 还原原始像素范围
    tmp = np.clip(tmp, 0, 1)  # 防止溢出

可视化流程说明

  1. 输入图像处理

    • 原始图像通过create_transform定义的多阶段变换
    • 包含典型操作:随机翻转(hflip=0.3)、中心裁剪(crop_pct=0.8)、归一化等
  2. 中间结果捕获

    intermediate_img = [img]  # 初始化包含原始图像
    for i in range(len(transform_list)):
        intermediate_img.append(transform_list[i](intermediate_img[i]))
    
    • 通过循环逐步应用每个变换并保存结果
  3. 结果可视化

    处理步骤关键技术
    PIL图像显示直接渲染Image.Image对象
    张量显示使用.permute(1,2,0)调整维度顺序(C×H×W → H×W×C)
    布局优化动态计算行列数,保证接近正方形排列(如5个子图显示为2×3网格)

实际应用场景

  • 代码演示:直观展示每个预处理步骤的效果
  • 算法调试:定位导致图像异常的变换步骤
  • 数据增强验证:检查随机裁剪/翻转是否合理
  • 模型部署:验证预处理与训练时的一致性
import os
import math
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
from timm.data.transforms_factory import create_transform
import torch

os.environ['KMP_DUPLICATE_LIB_OK'] = 'TRUE'

# Step1: 读取图片
img = Image.open('DJI_20241009083951.jpg')

# Step2: 创建图像变换组合
transform = create_transform(
    input_size=(224, 224),
    is_training=True,
    hflip=0.3,
    vflip = 0.1,
    crop_mode='border',
    crop_pct=0.8,
    mean=(0.485, 0.456, 0.406),
    std=(0.229, 0.224, 0.225)
)

# Step3: 显示变换组合
print(transform)
transform_list = transform.transforms  # 将所有变换放到列表中

# Step4: 生成中间结果
intermediate_img = [img]
for i in range(len(transform_list)):
    intermediate_img.append(transform_list[i](intermediate_img[i]))

# Step5: 动态计算子图布局
total_steps = len(intermediate_img)
cols = math.ceil(math.sqrt(total_steps))  # 列数
rows = math.ceil(total_steps / cols)      # 行数动态计算

# 创建子图(保持二维结构)
fig, axs = plt.subplots(rows, cols, figsize=(cols * 5, rows * 5), squeeze=False)

# Step6: 可视化所有中间结果
for i in range(total_steps):
    # 获取当前步骤的名称和图像
    name = "Original" if i == 0 else transform_list[i - 1].__class__.__name__
    img_step = intermediate_img[i]

    # 转换为可显示格式
    if isinstance(img_step, Image.Image):
        tmp = img_step
    elif isinstance(img_step, torch.Tensor):
        if name == "Normalize":
            # 反归一化处理
            mean = np.array(transform_list[i - 1].mean)
            std = np.array(transform_list[i - 1].std)
            tmp = img_step.permute(1, 2, 0).numpy() * std + mean
            tmp = np.clip(tmp, 0, 1)
        else:
            tmp = img_step.permute(1, 2, 0).numpy()

    # 计算子图位置
    row = i // cols
    col = i % cols

    # 绘制子图
    axs[row, col].imshow(tmp)
    axs[row, col].axis('off')
    axs[row, col].set_title(f"Step {i}: {name}", fontsize=8)

# 隐藏多余的空子图
for i in range(total_steps, rows * cols):
    row = i // cols
    col = i % cols
    axs[row, col].axis('off')

plt.tight_layout()
plt.show()

在这里插入图片描述

相关文章:

  • Java并发编程面试题:ThreadLocal(8题)
  • VIM FZF 安裝和使用
  • ClickHouse系列之ClickHouse安装
  • 8. MySQL 索引的创建与涉及原则(详解说明)
  • JavaScript函数-函数的使用
  • Ubuntu服务器 /data 盘需要手动挂载的解决方案
  • WPS PPT插入各种线型形状(如画直线)的时候总是有箭头,如何还原成只画直线
  • CSS垂直居中终极方案:告别复杂计算,拥抱现代布局
  • RocksDB Bloom Filter 如何避免假阳性问题探索
  • Ubuntu 22.04安装K8S集群
  • MySQL的Union和OR查询
  • 音乐创作新纪元:AI音乐网站的革命性力量
  • 大屏开源项目go-view二次开发1----环境搭建(C#)
  • AF3 make_template_features函数解读
  • 蓝桥杯备赛-基础训练(三)哈希表 day15
  • 特征提取:如何从不同模态中获取有效信息?
  • 中兴B863AV3.2-T/B863AV3.1-T2/B863AV3.1-T2K_电信高安_S905L3A-B_安卓9.0_线刷固件包
  • Python进行简单医学影像分析的示例
  • LLM Agent:PaSa
  • ipad连接电脑断断续续,不断弹窗的解决办法
  • 海南省三亚市委原常委、秘书长黄兴武被“双开”
  • 迪拜金融市场CEO:2024年市场表现出色,超八成新投资者来自海外
  • 美政府被曝下令加强对格陵兰岛间谍活动,丹麦将召见美代办
  • 调节负面情绪可以缓解慢性疼痛
  • 体坛联播|国米淘汰巴萨晋级欧冠决赛,申花击败梅州避免连败
  • 新质观察|“模速空间”如何成为“模范空间”