BSD100数据集入门指南:从零开始掌握图像超分辨率基准数据

1次阅读
没有评论

共计 2838 个字符,预计需要花费 8 分钟才能阅读完成。

image.webp

为什么选择 BSD100 数据集

BSD100(Berkeley Segmentation Dataset 100)是图像超分辨率(Super-Resolution, SR)领域的黄金标准之一,包含 100 张高质量自然场景图像。它的价值主要体现在:

BSD100 数据集入门指南:从零开始掌握图像超分辨率基准数据

  • 基准可比性:超过 70% 的超分辨率论文使用该数据集进行横向对比
  • 场景多样性:涵盖城市、自然、人物等丰富场景
  • 分辨率标准:所有图像统一为 481×321 或 321×481 像素

在超分辨率任务中,我们通常需要将低分辨率 (LR) 图像恢复为高分辨率 (HR) 版本。BSD100 的特殊之处在于其 HR 图像都是真实拍摄而非合成生成,这对模型的泛化能力提出更高要求。

数据集结构解析

下载解压后的目录结构如下:

BSD100/
├── HR/                 # 高分辨率图像
│   ├── 0801.png
│   └── ...
└── LR_bicubic/X4/      # 双三次降采样 4 倍的低分辨率图像
    ├── 0801x4.png
    └── ...

关键点说明:

  • 文件名对应规则:LR_bicubic/X4/0801x4.png 对应 HR/0801.png
  • 降采样倍数:官方提供 2×、3×、4×三种降采样版本
  • 图像格式:全部为 PNG 格式避免压缩伪影

数据加载实战

以下是使用 Python 进行数据加载的标准流程,我们同时比较 OpenCV 和 PIL 库的处理差异:

import cv2
from PIL import Image
import numpy as np
import os

# 配置数据集路径
data_dir = './BSD100'
hr_dir = os.path.join(data_dir, 'HR')
lr_dir = os.path.join(data_dir, 'LR_bicubic/X4')

# 使用 OpenCV 加载(注意 BGR/RGB 转换)def load_with_cv2(img_path):
    img = cv2.imread(img_path)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # 转换为 RGB 格式
    return img

# 使用 PIL 加载(保留 EXIF 信息)def load_with_pil(img_path):
    with Image.open(img_path) as img:
        img.load()  # 确保 EXIF 信息读取
        return np.array(img)

# 示例:加载配对的 HR/LR 图像
sample_id = '0801'
hr_img = load_with_pil(os.path.join(hr_dir, f'{sample_id}.png'))
lr_img = load_with_pil(os.path.join(lr_dir, f'{sample_id}x4.png'))

print(f'HR shape: {hr_img.shape}, LR shape: {lr_img.shape}')
# 输出示例:HR shape: (321, 481, 3), LR shape: (80, 120, 3)

预处理与增强技巧

标准化流程

# 归一化到 [0,1] 范围并转换为 Tensor
import torch

def normalize(img):
    img = img.astype(np.float32) / 255.0
    return torch.from_numpy(img).permute(2, 0, 1)  # HWC -> CHW

# 反向归一化(用于结果可视化)def denormalize(tensor):
    tensor = tensor.clamp(0, 1).permute(1, 2, 0)  # CHW -> HWC
    return (tensor.numpy() * 255).astype(np.uint8)

数据增强方案

  • 训练阶段:
  • 随机水平 / 垂直翻转(p=0.5)
  • 90 度随机旋转
  • 色彩抖动(亮度±0.1,对比度±0.1)

  • 测试阶段:

  • 仅中心裁剪保持尺寸一致
  • 绝对禁止使用任何随机变换
# 示例增强实现
from torchvision import transforms

train_transform = transforms.Compose([transforms.RandomHorizontalFlip(),
    transforms.RandomVerticalFlip(),
    transforms.ToTensor(),])

test_transform = transforms.Compose([transforms.ToTensor(),
])

降采样方法对比

BSD100 官方使用双三次插值(bicubic interpolation)生成 LR 图像,但实际研究中常需自定义降采样方法:

def downsample(img, factor=4, mode='bicubic'):
    h, w = img.shape[:2]
    new_h, new_w = h // factor, w // factor

    if mode == 'bicubic':
        return cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_CUBIC)
    elif mode == 'nearest':
        return cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_NEAREST)
    elif mode == 'lanczos':
        return cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_LANCZOS4)
    else:
        raise ValueError(f'Unknown mode: {mode}')

不同方法的视觉影响:

方法 计算耗时 边缘平滑度 伪影程度
最近邻 ★☆☆☆☆ ★☆☆☆☆ ★★★★☆
双线性 ★★★☆☆ ★★★☆☆ ★★☆☆☆
双三次 ★★★★☆ ★★★★☆ ★☆☆☆☆
Lanczos ★★★★★ ★★★★★ ★☆☆☆☆

性能评估指标

PSNR 计算

def psnr(hr, sr, max_val=1.0):
    mse = torch.mean((hr - sr) ** 2)
    return 10 * torch.log10(max_val ** 2 / mse)

SSIM 计算

from skimage.metrics import structural_similarity as ssim

def calc_ssim(hr, sr):
    # 转换为灰度计算(多通道需分别计算后取平均)return ssim(hr, sr, multichannel=True, data_range=1.0)

延伸思考

  1. 跨数据集训练:如何将 BSD100 与 DIV2K(800 张高质图像)结合使用?
  2. 方案一:先 DIV2K 预训练,再 BSD100 微调
  3. 方案二:混合训练时调整采样比例(如 DIV2K:BSD100=4:1)

  4. 真实场景适配:BSD100 的 LR 图像是理想降采样结果,如何模拟手机拍摄的真实模糊?

  5. 添加高斯模糊核
  6. 引入 JPEG 压缩伪影

  7. 评估优化:当 PSNR 提升但视觉效果变差时,可能是什么原因?

  8. 过度平滑导致高频信息丢失
  9. 指标与人类视觉感知不一致

参考文献

  1. BSD100 原始论文
  2. 超分辨率基准测试规范
  3. OpenCV 插值方法文档
正文完
 0
评论(没有评论)