医疗图像超分实战:从开源数据集寻找、退化构建到下载踩坑全记录

2 阅读6分钟

💡 为什么学这个?

最近在推进一个内镜图像超分辨率模型项目。我需要一批高质量的内镜超分数据集。

原以为像通用 CV 领域一样,随便找个带有 LR(低清)和 HR(高清)配对的数据集跑一下就行,结果在医疗图像这个细分领域结结实实地碰了壁。通过这几天的摸索,我把内镜超分数据集的寻找、退化构建、到踩坑下载的整个闭环跑通了。在这里做个复盘,希望能帮到做类似方向的算法同行。


🛠️ 核心内容与实操步骤

1. 认清现实:医疗超分领域没有“天然配对”的数据

在医学图像(尤其是内镜)超分领域,几乎没有任何公开数据集会直接提供 LR-HR(低清-高清)的配对数据。原因很简单:在真实的手术中,不可能同时把 4K 和 720P 两根内镜探头插到同一个位置去拍摄完美对齐的照片。

因此,学术界和工业界的标准玩法是:寻找公开的“高清/4K内镜数据集”作为 Ground Truth,然后通过代码人工退化(降采样、加噪),生成对应的低清图像。

2. 优质开源内镜数据集盘点

经过调研,目前比较主流且质量较高的高清内镜数据集有以下几个:

  • SurgiSR4K (2025最新) :极其少见的以原生 4K 分辨率捕获的微创手术数据集,非常适合做前沿的超分大模型底座。
  • HyperKvasir (最推荐) :规模极大的胃肠道内镜开放数据集,包含十多万张图像,且完全开源易获取,极其适合用来做工程验证和 INT8 校准。
  • PICCOLO Dataset:专门针对结肠息肉的高分辨率数据集,特色是包含窄带成像(NBI)图像,有很高的临床辅助价值。
  • Hamlyn & Cholec80:经典的视频数据集,适合做包含时序信息的视频超分(VSR)研究,但申请比较严格。

3. 构建标准基准测试集 (Benchmark)

拿到了类似 HyperKvasir 的高清原图后,我们需要自己写代码构建标准的基准测试目录结构。业界最经典的退化方式是 BI 退化 (Bicubic Downsampling)

核心处理逻辑很简单:

  1. 读入高清原图(HR)。
  2. 为了保证缩小再放大后尺寸不出现偏差,先对 HR 图像按照超分倍数(Scale)进行模裁剪(ModCrop)。
  3. 使用双三次插值(Bicubic)将其缩小指定倍数,保存为 LR 图像。
  4. 最终构建出 HR/LR_bicubic/X2/ 这样标准的成对目录,直接喂给测试脚本跑评估。 (具体实现代码见文末附录)

🚨 遇到的问题与解决方法

在下载这些几十上百 GB 的医疗数据集时,我遇到了几个经典的工具链坑:

问题一:HuggingFace 下载疯狂刷屏警告

现象:用 datasets.load_dataset 下载 SurgiSR4K 时,控制台疯狂打印:Xet Storage is enabled... falling back to regular HTTP download.

原因:该仓库启用了 Xet Storage 加速技术,但我本地没装对应的加速包,导致退化成了极慢的普通 HTTP 单文件下载。

解决:中断运行,终端执行 pip install "huggingface_hub[hf_xet]" 安装底层加速依赖,重新运行后不仅警告消失,速度也起飞了。

问题二:C盘空间告急(缓存路径问题)

现象:HuggingFace 默认把几十 GB 的 Arrow 缓存文件塞到了 ~/.cache/huggingface/datasets,直接把我的系统盘干爆了。

解决:在代码中显式指定 cache_dir 参数,或者一劳永逸地在系统环境变量中设置 HF_DATASETS_CACHE=/your/custom/path,将其重定向到数据盘。

问题三:医疗数据集权限获取繁琐

现象:有些著名数据集(如 Cholec80)没有直接的下载链接,需要发邮件、签协议(EULA)。

解决:明确当前阶段的核心诉求。我目前的诉求是“验证模型部署流水线与评估脚本”,而不是“刷学术 SOTA”。因此果断放弃繁琐的申请,转向无需鉴权、完全开源HyperKvasir,挑出里面最清晰的 100 张图瞬间搞定基准测试集的构建。

(注:另外分享个日常找数据的技巧:找野生数据多用 Kaggle API kaggle datasets download,找 TB 级别超大医疗影像多去 Academic Torrents 找种子挂机下。)


📝 收获与总结

  1. 工程思维的转变:做算法落地,不要死磕找不到的完美数据。理解了超分任务“人工构建退化模型”的本质后,所有的高清图片都可以成为我的训练集和校准集。
  2. 基建的重要性:在做核心模型前,把预处理流水线(100% 字节级对齐的读图、裁剪、退化逻辑)先写扎实,能为后期 TensorRT 部署和精度对比省下无数个挠头的夜晚。
  3. 工具链的熟练度:掌握 HuggingFace、Kaggle API 的高级用法(如缓存管理、加速包配置),是提升日常算法开发效率的必备基本功。

📎 附录:一键生成退化数据集 (Benchmark) 脚本

以下是我编写的用于自动构建标准 SR 测试集的 Python 脚本。它会遍历 HR 高清图目录,自动进行 ModCrop 和 Bicubic 降采样,并严格按照业界基准的目录树(HRLR_bicubic/XN)进行组织,可直接用于 PSNR/SSIM 的批量评测。

Python

import os
import glob
from PIL import Image
from tqdm import tqdm

def generate_lr_dataset(hr_dir, output_root, dataset_name="EndoDataset", scale=2):
    """
    根据 HR (高清) 图像,自动生成对应的 LR (低清) 图像,并构建标准测试集目录结构。
    """
    
    # 1. 创建目标目录
    out_hr_dir = os.path.join(output_root, dataset_name, 'HR')
    out_lr_dir = os.path.join(output_root, dataset_name, 'LR_bicubic', f'X{scale}')
    
    os.makedirs(out_hr_dir, exist_ok=True)
    os.makedirs(out_lr_dir, exist_ok=True)
    
    # 2. 获取所有 HR 图像
    valid_exts = ('*.png', '*.jpg', '*.jpeg', '*.bmp')
    hr_files = []
    for ext in valid_exts:
        hr_files.extend(glob.glob(os.path.join(hr_dir, ext)))
        hr_files.extend(glob.glob(os.path.join(hr_dir, ext.upper())))
        
    if not hr_files:
        print(f"❌ 在 {hr_dir} 下没有找到任何图像文件!")
        return

    print(f"🚀 开始处理 {len(hr_files)} 张图像,超分倍数: x{scale}")
    
    for img_path in tqdm(hr_files, desc="Generating LR/HR pairs"):
        filename = os.path.basename(img_path)
        
        try:
            # 打开原图
            img_hr = Image.open(img_path).convert('RGB')
            w, h = img_hr.size
            
            # ModCrop 模裁剪:确保高和宽都能被 scale 整除
            w_mod = w - (w % scale)
            h_mod = h - (h % scale)
            
            if w != w_mod or h != h_mod:
                img_hr = img_hr.crop((0, 0, w_mod, h_mod))
                
            # 保存标准的 HR 图像为无损 PNG
            save_hr_path = os.path.join(out_hr_dir, filename)
            img_hr.save(save_hr_path, format='PNG')
            
            # 生成 LR 图像 (Bicubic 缩小)
            lr_w = w_mod // scale
            lr_h = h_mod // scale
            img_lr = img_hr.resize((lr_w, lr_h), resample=Image.BICUBIC)
            
            # 保存标准的 LR 图像
            save_lr_path = os.path.join(out_lr_dir, filename)
            img_lr.save(save_lr_path, format='PNG')
            
        except Exception as e:
            print(f"⚠️ 处理图像 {filename} 时出错: {e}")

    print(f"✅ 数据集构建完成!保存在: {os.path.join(output_root, dataset_name)}")


if __name__ == "__main__":
    # 配置参数示例
    SOURCE_HR_DIR = "./downloads/HyperKvasir_HighRes"  # 原始高清图路径
    BENCHMARK_ROOT = "./data/benchmark"              # Benchmark 根目录
    DATASET_NAME = "HyperKvasir_Test"                # 自定义数据集名称
    SCALE = 2                                        # 超分倍数
    
    if os.path.exists(SOURCE_HR_DIR):
        generate_lr_dataset(SOURCE_HR_DIR, BENCHMARK_ROOT, DATASET_NAME, SCALE)
    else:
        print(f"请先创建 {SOURCE_HR_DIR} 并放入下载的高清内镜图片。")