💡 为什么学这个?
最近在推进一个内镜图像超分辨率模型项目。我需要一批高质量的内镜超分数据集。
原以为像通用 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) 。
核心处理逻辑很简单:
- 读入高清原图(HR)。
- 为了保证缩小再放大后尺寸不出现偏差,先对 HR 图像按照超分倍数(Scale)进行模裁剪(ModCrop)。
- 使用双三次插值(Bicubic)将其缩小指定倍数,保存为 LR 图像。
- 最终构建出
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 找种子挂机下。)
📝 收获与总结
- 工程思维的转变:做算法落地,不要死磕找不到的完美数据。理解了超分任务“人工构建退化模型”的本质后,所有的高清图片都可以成为我的训练集和校准集。
- 基建的重要性:在做核心模型前,把预处理流水线(100% 字节级对齐的读图、裁剪、退化逻辑)先写扎实,能为后期 TensorRT 部署和精度对比省下无数个挠头的夜晚。
- 工具链的熟练度:掌握 HuggingFace、Kaggle API 的高级用法(如缓存管理、加速包配置),是提升日常算法开发效率的必备基本功。
📎 附录:一键生成退化数据集 (Benchmark) 脚本
以下是我编写的用于自动构建标准 SR 测试集的 Python 脚本。它会遍历 HR 高清图目录,自动进行 ModCrop 和 Bicubic 降采样,并严格按照业界基准的目录树(HR 与 LR_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} 并放入下载的高清内镜图片。")