ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

蝴蝶显微图像数据集:超分与去噪模型训练全流程

蝴蝶显微图像数据集:超分与去噪模型训练全流程 简介显微图像下的蝴蝶数据集源自论文《Deep learning super-resolution electron microscopy based on deep residual attention network》专为深度学习与显微图像任务设计可用于超分辨率重建、去噪及图像恢复等方向尤其适合复现残差注意力网络的训练流程。压缩包共205个文件以PNG格式的显微蝴蝶图像为主共200张图像保留了较为完整的纹理与细节能够覆盖不同视野和结构为模型提供多样化训练样本另含1个MATLAB脚本可对原始高清图像进行下采样与裁剪自动生成高/低分辨率配对数据省去手动预处理的繁琐步骤。PNG格式可避免压缩伪影更真实地评估超分/去噪模型对细节的还原能力同时数据规模适中既保证样本多样性又便于在单卡GPU环境下快速迭代。该数据集原发布链接已失效作者重新打包上传避免了外网访问缓慢、下载中断等问题方便国内研究者直接获取目前已有163人学习下载。适合需要复现论文实验、开展显微图像超分或去噪研究的科研人员和算法工程师。1. 显微图像下的蝴蝶数据集把超分与去噪模型先“喂饱”再谈参数用四倍物镜拍蝶翅100% 显示时鳞片轮廓清晰放大到 800% 后边缘全是锯齿想靠锐化补救噪声也跟着一起被放大了。显微图像和普通照片的退化分布差异很大拿自然图像数据训练的模型直接迁移往往要么把鳞片细节磨平要么在暗区生成彩色噪点。显微图像下的蝴蝶数据集把超分、去噪两条任务线收到了同一套数据上鳞片表面有周期性肋脉天然提供了密集的高频结构和可重复的纹理先验成像链路里的泊松噪声、读出噪声、渐晕与离焦又同时出现任何单一退化假设都很难糊弄过去。这套数据的实际价值是同时产出三份样本清晰的高倍 HR、经光学退化与下采样的 LR、带真实强度噪声的噪声图。做显微图像增强、低成本系统软升级以及高噪声环境下信号恢复的工程师都能靠它先验证模型方向再调参。后面内容不会停在“去网上下载”这一步而是把构建、训练、验证的路径完整跑通让这套数据集能复用到其他显微任务里。2. 蝴蝶显微图为什么适合超分与去噪从纹理规律到噪声拆解2.1 鳞片肋脉是天然的高频重复结构超分模型能从中借力病理切片或细胞图像的边缘方向分散样本间差异极大超分模型要在“编造结构”和“恢复结构”之间摇摆。蝴蝶鳞片不一样。鳞片表面的纵肋与横脊形成周期性光栅肋脉间距和方向在局部保持稳定对超分模型来说相当于反复出现的先验这一块缺掉的条纹在相邻十几微米的范围内能找到高度相似的参考。去噪模型也有好处高频能量集中在确定的方向信号与随机噪声在频域上更容易区分。常见做法是先做频谱检查再决定数据集是否可用python - EOF import cv2, numpy as np img cv2.imread(scale_check.png, 0).astype(np.float64) f np.fft.fftshift(np.fft.fft2(img)) spec np.log(np.abs(f) 1e-8) print(spectrum_peak_ratio, spec.max() / (spec.mean() 1e-8)) cv2.imwrite(fft_spec.png, (spec / spec.max() * 255).astype(uint8)) EOFspectrum_peak_ratio数值越大说明频谱里方向性亮线越明显纹理主轴越单一后续超分不容易出现方向性伪影。如果数值接近 1频谱能量散成一团说明样本结构不典型就应该换一张视野重新评估。这个检查在构建数据集时对每张图跑一遍即可不需要进入训练流程。2.2 显微成像的噪声来源光子噪声、读出噪声与渐晕要分开记账显微镜图像里的噪声不是单一的加性高斯。低光条件下光子到达传感器符合泊松分布而暗电流和传感器读出过程会叠加上近高斯分布的噪声照明光路不均匀还会造成渐晕让视野四周亮度基线低于中心且抑制了原本就较暗的鳞片边缘信号。如果把这些退化混成一个“高斯白噪声”处理去噪模型很容易把暗角当成信号压掉超分模型则会在边缘区域学到错误的锐化强度。因此显微图像数据集不能只存图片。每个视野必须附带元数据至少包含物镜倍数、数值孔径 NA、曝光时间、ISO、照明强度、是否做过 Z-堆叠合并。暗电流明显的相机还要单独拍一张同曝光的暗帧在预处理阶段减掉否则低光样本的信噪比会被系统性地压低。去噪训练时同一张 HR 可以衍生出不同噪声级别的 LR但元数据字段必须保持一致否则验证集上的 PSNR 没有可比性。2.3 与其他公开显微数据集的差异形态密度与划分泄漏光学显微图像数据集常见的毛病是前景占比低大块空白背景里只分布着稀疏的细胞或纤维模型大量算力浪费在均匀区域。蝴蝶翅膀标本几乎整个视野都是鳞片有效信息密度高同样的 batch size 下收敛速度要快不少。但高信息密度也带来一个隐藏风险——同一只蝴蝶的重复纹理会让指标虚高。训练里出现过某个视野验证集再用该视野的相邻切块PSNR 会虚高 0.5~1dB而这个提升在真实应用里根本不存在。验证数据划分是否泄漏用文件名前缀判断即可from pathlib import Path from collections import defaultdict def check_leak(train_dir, val_dir): groups defaultdict(set) for p in list(Path(train_dir).glob(*.png)) list(Path(val_dir).glob(*.png)): parts p.stem.split(_)[:2] # 如 spec-03_x12 key _.join(parts) groups[key].add(train if str(p).startswith(train) else val) leaked {k: v for k, v in groups.items() if len(v) 1} return leaked如果返回结果非空说明同一视野的切块同时进入了训练和验证需要重建划分。显微图像数据集本身并不稀缺真正影响训练效果的不是图像数量而是退化对是否配准、元数据是否完整、视野级划分是否严格执行这三件事。3. 构建可训练的显微图像数据集采集规范与退化对生成3.1 采集端参数物镜、齐焦与 Z-堆叠要得到干净的 HR常见做法是用 4 倍或 10 倍物镜拍全局视野再切换到 40 倍物镜对同一坐标拍摄局部区域作为超分任务的 GT。拍摄时有三个点容易忽略。载物台移动后必须重新自动对焦避免载玻片倾斜让视野一侧发虚低倍物镜景深不足要用 Z-堆叠以 1~2μm 步长采集多层焦面并合成全焦图像曝光参数要记录暗电流明显的传感器需要额外拍一张同曝光暗帧用于扣除。操作步骤可以按下面顺序执行。低倍下拍完整翅膀选翅脉交点处 10~20 个坐标点切到 40 倍对每个坐标点做 Z-堆叠采集导出 TIFF 序列后按坐标编号保存最后把暗帧扣除和全焦融合一次性做完。文件名建议带采集条件例如spec-03_x12_y08_40x.tif。这套流程能保证后续超分训练时 GT 与 LR 的物理对应关系清晰不会因为硬件坐标误差产生像素级错位。3.2 从 HR 生成 LR 与噪声对退化函数与参数表显微镜成像链路可以近似写成LR D(HR; k) n。先由光学点扩散函数造成模糊再做像素合并最后叠加光子噪声与读出噪声。低倍下重新拍一套图当然可行但硬件坐标误差无法保证像素级对齐常见做法是直接用单张真实 HR 做数字退化得到严格对齐的 LR。import cv2, numpy as np def create_paired_data(hr_rgb, scale4, ksize11, sigma_k1.0, photon40, sigma_n5): kernel cv2.getGaussianKernel(ksize, sigma_k) kernel kernel kernel.T # 各向异性 PSF 近似 blurred cv2.filter2D(hr_rgb, -1, kernel, borderTypecv2.BORDER_REFLECT) h, w blurred.shape[:2] h, w h - h % scale, w - w % scale # 保证可整除 blurred blurred[:h, :w] lr cv2.resize(blurred, (w // scale, h // scale), interpolationcv2.INTER_AREA) photon_noise np.random.poisson(lr * photon) / photon gauss_noise np.random.normal(0, sigma_n / 255.0, lr.shape) lr np.clip(photon_noise gauss_noise, 0, 1) return lr, blurred[:h, :w]sigma_k控制在 0.8~1.6对应普通消色差物镜在目标倍率下的剩余离焦photon取 20~80数值越小光子噪声越强用来模拟暗场或低曝光条件sigma_n是 255 尺度标准差5~15 对应常见 CMOS 在中等增益下的读出噪声。生成训练数据前务必固定随机种子否则验证阶段每次生成的 LR 都不同指标波动会掩盖真实差距。退化来源与建议参数可参照下表退化来源参数名建议范围说明离焦 PSFksize / sigma_k9~15 / 0.8~1.6物镜 NA 越高模糊半径越小像素合并scale2 / 4对应物镜倍率差光子噪声photon20~80曝光时间缩短则数值减小读出噪声sigma_n0~15ISO 升高则增大暗角半径掩码中心 0 到边缘 20%可选给去噪模型增加难度3.3 数据集目录布局与 JSON 元数据推荐目录结构如下butterfly-ds/ train/hr/ train/lr_x4/ train/noisy/ val/hr/ val/lr_x4/ val/noisy/ test/hr/ test/lr_x4/ test/noisy/ metadata.jsontrain 与 val 按视野划分train 里出现的视野编号不允许进入 val。metadata.json 中每张图对应一个条目包含原始文件名、物镜倍数、scale、sigma_k、photon、sigma_n。训练脚本运行时直接读取该文件统一下发参数而不是靠文件名去猜。去噪任务的 noisy 目录建议直接从 HR 加噪生成暗角项可以通过环形掩码叠加进去让去噪模型学会分辨照明不均匀与真实信号。4. 用蝴蝶显微图像训练超分与去噪模型的实际路径4.1 用 BasicSR 跑 SwinIR最小可复现配置常见做法是拿 BasicSR 仓库里的 SwinIR 配置改数据集路径。这份 YAML 是按显微图像场景调整后的最小配置name: swinir_srx4_butterfly model_type: SRModel scale: 4 datasets: train: type: PairedImageDataset dataroot_gt: ./butterfly-ds/train/hr dataroot_lq: ./butterfly-ds/train/lr_x4 gt_size: 128 use_hflip: true use_rot: true val: type: PairedImageDataset dataroot_gt: ./butterfly-ds/val/hr dataroot_lq: ./butterfly-ds/val/lr_x4 network_g: type: SwinIR upscale: 4 in_chans: 3 img_size: 64 window_size: 8 depths: [6, 6, 6, 6] num_heads: [6, 6, 6, 6] train: optim_g: type: Adam lr: !!float 2e-4 total_iter: 300000 scheduler: type: MultiStepLR milestones: [150000, 225000] gamma: 0.5 val_freq: 5000 manual_seed: 42gt_size: 128表示训练时随机裁剪 128×128 的 HR 块足够覆盖蝴蝶肋脉的局部周期img_size: 64对应 SwinIR 内部窗口划分基本尺寸window_size: 8必须与之配套改错会在训练时报窗口越界。学习率按 2e-4 起步蝴蝶纹理高频密集不建议第一轮就降到 1e-4 以下。启动命令为python basicsr/train.py -opt options/train/swinir_srx4_butterfly.yml训练日志每隔val_freq个 iter 输出一次 PSNR 和 SSIM两个指标在同一条 log 里方便观察训练是否震荡。先跑 3000 iter 做 smoke test确认 loss 在稳定下降后再放开到完整配置。4.2 自定义 Dataset 类实时生成 LR 与噪声图如果训练时实时做退化硬盘上可以只留 HR减小数据集体积。自定义 Dataset 的核心逻辑如下import torch, cv2, numpy as np from torch.utils.data import Dataset from pathlib import Path class ButterflyDegradeDataset(Dataset): def __init__(self, hr_dir, scale4, gt_size128, seed0): self.hr_paths sorted(Path(hr_dir).glob(*.png)) self.scale, self.gt_size, self.seed scale, gt_size, seed def __len__(self): return len(self.hr_paths) def __getitem__(self, idx): hr cv2.imread(str(self.hr_paths[idx])).astype(np.float32) / 255.0 h, w hr.shape[:2] h, w h - h % self.scale, w - w % self.scale hr hr[:h, :w] x np.random.randint(0, h - self.gt_size 1) y np.random.randint(0, w - self.gt_size 1) hr hr[x:xself.gt_size, y:yself.gt_size] rng np.random.default_rng(self.seed idx) lr, _ create_paired_data( hr, scaleself.scale, photonint(rng.integers(20, 80)), sigma_nfloat(rng.integers(0, 15))) return torch.from_numpy(lr.transpose(2, 0, 1)).float(), \ torch.from_numpy(hr.transpose(2, 0, 1)).float()这里create_paired_data复用 3.2 节的退化函数。每次取样本时photon 和 sigma_n 在预设范围内随机相当于退化参数增强。同一张 HR 在多次采样时获得不同噪声水平模型对噪声强度和 PSF 变化的鲁棒性会更好。显存紧张时把gt_size降到 64窗口相关配置无需修改。4.3 数据泄漏、尺寸对齐与归一化的排错要点数据泄漏在第 2.3 节已经给过检测方法不再展开。尺寸对齐是第二个高频坑HR 裁到 128×128 后必须整体做模糊下采样不能先缩原图再裁块否则 LR 与 HR 的像素相位不对齐模型只能学到平均模糊收敛后 PSNR 大约低 1.5dB。注意先把 LR 的边长是否为 HR 的 1/scale 作为基本检查项。若 decoder 输出尺寸比 GT 少 1 像素回退化函数检查取余逻辑而不是改网络输出尺寸。数值范围是第三个坑。显微 TIFF 可能是 16 位读取时不除以 65535 而直接当 uint8 处理整张图亮度会被压到极低范围训练初期 loss 很难下降。建议在预处理脚本里统一转成 0~1 的 float32 并保存为 PNG训练阶段不再做任何归一化。4.4 去噪任务复用同一批蝴蝶显微图像超分与去噪共用一套 HR 是这套数据集最大的便利。去噪时把 nois y 目录当作 LQhr 目录当作 GT网络结构换成普通去噪网络或直接沿用 SwinIR 都可。唯一要改的是 YAML 里的dataroot_lq和scale去噪没有尺寸变化scale: 1gt_size可以提高到 256。如果不想做分辨率变化退化函数里把scale固定为 1只保留模糊与噪声项即可。5. 验证与坑评估指标与可复现的跑通脚本5.1 固定边界的 PSNR/SSIM超分与去噪验证都要裁掉图像边界边界填充会拉低指标。代码实现如下import cv2, math import numpy as np from skimage.metrics import structural_similarity as ssim def calc_psnr_ssim(hr_bgr, sr_bgr, border4): hr hr_bgr.astype(np.float64) sr sr_bgr.astype(np.float64) h, w hr.shape[:2] hr_c hr[border:h-border, border:w-border] sr_c sr[border:h-border, border:w-border] mse np.mean((hr_c - sr_c) ** 2) psnr 10 * math.log10(255.0 ** 2 / mse) ssim_val ssim(hr_c, sr_c, channel_axis2, data_range255) return psnr, ssim_valborder取 4 时SSIM 使用的恰好是去掉边界后的区域。如果 mse 为 0说明两张图完全相同需要单独判空。肉眼确认时把 HR 与 SR 做差再乘 5 倍显示残差如果集中在肋脉方向说明结构恢复不足如果随机散布说明主要是噪声残留。5.2 无参考指标NIQE 与三个固定观察点PSNR 和 SSIM 是有参考指标真实测试场景下往往拿不到 GT还要配合 NIQE 使用niqe --ref test/hr/001.png --dist test/sr/001.png肉眼判读固定看三个位置鳞片边缘是否有振铃肋脉交叉点是否断裂背景暗区是否出现彩噪。这三个点同时通过参数调整才有继续下去的价值。5.3 验证管线的快速启动方式推荐先用test目录里同一视野的 10 张 HR 跑一次前向推理确认输出 shape、数值范围和指标都正常再跑 1000 iter 的短训练观察 loss 曲线是否在 20 iter 内下降确认数据链路无误后再上全量参数搜索。显存不够时可以把大图切成 256×256 的重叠块推理重叠区域做线性融合避免拼接缝在蝶翅暗区背景下被放大。每次修改 YAML 后清掉旧 log 和权重缓存BasicSR 不会自动识别配置变更残留的 iter 状态会让结果看起来不可复现。退化参数统一记录进 metadata超分与去噪共用一套评估脚本训练、验证、批处理全由一条命令触发这套数据集才算真正落地。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进