显微图像超分数据集解析:蝴蝶数据集及Python迁移指南
2026/9/13 11:41:54 网站建设 项目流程

简介:显微图像下的蝴蝶数据集源自论文《Deep learning super-resolution electron microscopy based on deep residual attention network》,面向从事深度学习图像超分、去噪、显微图像复原等底层视觉任务的研究者与开发者。原论文提供的下载链接已失效且访问缓慢,现重新打包上传,解决获取门槛。压缩包共205个文件,大小94.39MB,核心为200张PNG格式显微图像,保留了电子显微镜下的织构细节,可直接划分训练集与测试集;另含1个MATLAB预处理脚本(Prepare_TestData_HR_LR.m),用于自动生成HR/LR高低分辨率配对数据,简化评估流程。该资源适合复现论文中的超分实验,也可用于验证不同去噪算法在真实显微噪声下的鲁棒性,或借助内容丰富的显微图像做数据增强、退化模型测试。PNG文件可无缝加载到PyTorch、TensorFlow等框架中,数据准备成本低。目前已有163人学习下载,属于小体量但针对性强的数据集,对需要真实显微图像样本的科研场景颇为实用。

1. 显微图像超分缺数据?蝴蝶数据集把HR/LR对一次性备齐

做超分和去噪的都知道,自然图像数据集一大把,可一旦换到显微图像领域,能用的公开基准就少得可怜。这篇博客要聊的蝴蝶数据集来自论文Deep learning super-resolution electron microscopy based on deep residual attention network,原发布链接已经慢到基本打不开,下载成功率很低。我把它重新整理后,发现里面既有完整的高分辨率显微图,也带了一个生成退化图像的 MATLAB 脚本Prepare_TestData_HR_LR.m,很适合用来做超分、去噪以及退化模型对比实验。对正在找显微图像训练集、或者想验证深度残差注意力网络在电镜图像上效果的人来说,这个数据集可以直接当成 SISR 的 benchmark 使用,省去自己去 SEM/TEM 图上标定和切块的麻烦。下面从文件构成开始,把它彻底拆开。

2. 数据集构成拆解:PNG 样本与 Prepare_TestData_HR_LR.m 的职责

2.1 目录里那几类文件的真实角色

解压后你会看到一堆.DS_Store、若干编号的 PNG 文件,以及一个 MATLAB 脚本。.DS_Store是 macOS 自动生成的元数据文件,在 Linux 或 Windows 上没有任何用处,直接删掉即可。真正有价值的是 82.png、93.png、94.png、81.png、92.png 这类命名不连续的 PNG,它们就是论文里用于测试或训练的高分辨率显微图像。

从文件编号跨度推测,原始数据集应该不止这几张,可能作者只选取了部分代表性切片上传。每张 PNG 都是完整的电镜灰度图,分辨率较高,但具体像素尺寸需要你加载后确认。这类图的共同特征是背景噪声明显、边缘纹理密集、结构重复度高,非常适合用来检验超分模型在周期性纹理上的重建能力。

那个.m脚本才是整个数据集的核心工具。它的名字Prepare_TestData_HR_LR.m已经说明了任务:把 HR 图像切成测试块,并生成对应的 LR 版本。这样你不需要自己写退化代码,直接用脚本就能得到和论文一致的 HR/LR 对。

2.2 MATLAB 脚本做了什么:从 HR 切块到生成双三次退化 LR

2.2.1 脚本核心逻辑

我重新读了一遍这个脚本,它的流程非常典型,可以概括为三步:遍历所有 PNG、按固定步长裁剪出若干子块、对每个子块做双三次下采样得到 LR。核心代码逻辑大致如下:

% 读取原始 HR 图像 hr_img = imread('93.png'); if size(hr_img, 3) == 3 hr_img = rgb2gray(hr_img); % 转灰度 end % 定义裁剪参数 patch_size = 128; % 子块边长 stride = 64; % 滑动步长,控制重叠率 scale = 4; % 超分倍率 % 生成 LR 图像:先模糊再下采样 lr_img = imresize(hr_img, 1/scale, 'bicubic');

这段脚本的重点在于imresize'bicubic'参数。MATLAB 的imresize默认使用双三次核,但在下采样前没有显式加抗混叠滤波器,这一点和论文里描述的双三次退化略有出入。实际使用时,我建议在imresize之前先调用imgaussfilt(hr_img, 1.5)做一次高斯模糊,模拟光学系统的点扩散效应,这样生成的 LR 更接近真实显微图像退化。

2.2.2 参数与常见修改点

脚本里最值得调整的是patch_sizestridescale。在显微图像场景下,我一般这样设置:

参数推荐值说明
patch_size128 或 192太大会导致训练样本数不足,太小则丢失上下文信息
stridepatch_size 的 1/2 或 1/4重叠越多,样本越丰富,但训练集膨胀
scale2、3、4论文主要验证 4 倍超分,2 倍适合去噪任务

如果你用的是 Python,完全不需要在 MATLAB 里跑这个脚本。可以用 OpenCV 复现同样的流程,但要注意cv2.resize的插值核和 MATLAB 有细微差异,后面第 5 章会专门讲这个坑。

3. 用蝴蝶数据集跑通 SISR 训练:从像素域到深度残差注意力网络

3.1 先把 PNG 读成可直接训练的 lmdb 或内存张量

拿到 HR 图后,第一步是切块并制作训练集。PyTorch 生态里最常见的做法是把所有切好的 HR/LR 对打包进 LMDB,避免训练时频繁小文件 IO。这里给出一个标准的制作流程:

import cv2 import numpy as np import lmdb import os def prepare_lmdb(hr_dir, lr_dir, lmdb_path): env = lmdb.open(lmdb_path, map_size=1024**3 * 4) txn = env.begin(write=True) idx = 0 for name in sorted(os.listdir(hr_dir)): if not name.endswith('.png'): continue hr = cv2.imread(os.path.join(hr_dir, name), cv2.IMREAD_GRAYSCALE) lr = cv2.imread(os.path.join(lr_dir, name), cv2.IMREAD_GRAYSCALE) # 存为二进制字符串,key 为序号 txn.put(f'hr_{idx}'.encode(), hr.tobytes()) txn.put(f'lr_{idx}'.encode(), lr.tobytes()) idx += 1 txn.commit() env.close()

这段代码把 HR 和 LR 图以原始字节存入 LMDB,map_size设为 4GB,足够容纳显微图像切块后的数据。需要注意的是 key 使用hr_0lr_0这类统一前缀,方便 DataLoader 按索引读取。实际训练时,你还需要记录每张图的原始尺寸,因为tobytes()丢掉了形状信息,读取时要根据预先保存的 shape 做 reshape。

3.2 训练时的数据增强与退化策略

3.2.1 常见超分任务的退化参数

显微图像超分和自然图像超分有一点关键区别:自然图像常常用随机缩放、随机旋转做增强,但显微图像的结构方向往往有物理意义,比如细胞膜的方向、纳米管的走向。如果随意旋转 90 度,可能引入不存在的各向异性。

我一般只做水平和垂直翻转,以及 90 度的整数倍旋转,不碰任意角度旋转。另外,由于电镜图像本身有噪声,训练时会对 LR 图像额外加不同程度的噪声,模拟低信噪比条件。下面是一个常用的退化与增强流程:

# 训练时动态生成 LR def degrade(hr_patch, scale=4, noise_level=0.0): # 高斯模糊模拟点扩散 k = cv2.getGaussianKernel(5, 1.5) hr_blur = cv2.filter2D(hr_patch, -1, k) # 下采样 lr = cv2.resize(hr_blur, (hr_patch.shape[1]//scale, hr_patch.shape[0]//scale), interpolation=cv2.INTER_CUBIC) # 加噪声,noise_level 为高斯噪声标准差 if noise_level > 0: noise = np.random.normal(0, noise_level, lr.shape) lr = np.clip(lr + noise, 0, 255).astype(np.uint8) return lr

这里的高斯核大小5和标准差1.5是经验值。如果你的显微图像分辨率很高,可以适当增大核的尺寸。注意cv2.filter2D是对 HR 图做模糊,而不是对 LR 图,这样才符合图像采集时的物理过程。

3.2.2 为什么显微图像要用各向同性退化

显微镜的点扩散函数通常是各向同性的,所以退化核应该近似圆形对称。如果用各向异性的高斯核(比如横向标准差大、纵向标准差小),会人为引入方向性模糊,导致模型学到错误的重建先验。因此,我在生成 LR 时坚持使用cv2.getGaussianKernel然后做外积得到二维各向同性核,而不是直接调用cv2.GaussianBlur后下采样。

3.3 评价指标与验证协议

超分模型在蝴蝶数据集上的评估,论文中使用的是 PSNR 和 SSIM。但显微图像有一个特点:背景区域占比较大,平坦区域的 PSNR 会拉高整体分数,掩盖边缘重建的不足。我通常会在验证时额外计算边缘区域的 PSNR,做法是先对 HR 和 SR 图做 Canny 边缘检测,只统计边缘像素位置的误差。

具体验证命令如果用 Python 计算 PSNR,需要注意数据类型转换:

def psnr(img1, img2): mse = np.mean((img1.astype(np.float64) - img2.astype(np.float64)) ** 2) if mse == 0: return float('inf') return 10 * np.log10(255.0**2 / mse)

这里必须把 uint8 转成 float64,否则减法结果会溢出,导致 MSE 计算错误,这是一个非常隐蔽的 bug。

4. 去噪与超分的联合任务:蝴蝶数据集的另一种打开方式

4.1 用同一批图构建噪声-干净对

蝴蝶数据集里的 HR 图虽然是采集得到的,但也可以当成干净的 ground truth。要去做噪任务,你可以模仿真实电镜噪声的分布。电镜图像噪声通常由泊松噪声和高斯噪声混合构成,其中泊松部分与信号强度相关。

构建训练对的常见做法是把 HR 图当作干净图像,然后对每个像素施加信号相关的噪声。下面是一个生成模拟噪声图的片段:

def add_microscope_noise(hr, peak=100): # 归一化到 [0,1] img = hr.astype(np.float64) / 255.0 # 泊松噪声:每个像素的期望值等于原值乘以 peak noisy = np.random.poisson(img * peak) / peak # 加高斯噪声 noisy = noisy + np.random.normal(0, 0.02, img.shape) return np.clip(noisy, 0, 1) * 255

这里的peak参数控制泊松噪声的强度。peak越小,噪声越强。如果peak设为 255,就和普通的高斯噪声接近。我在实际实验中,peak取 50 到 150 之间比较能模拟出低剂量电镜图像的噪感。

4.2 盲去噪与真实噪声模拟的差异

直接加泊松-高斯混合噪声的好处是简单,能和超分退化分开研究。但真实显微图像的噪声与设备状态、电子束剂量、探测器响应都有关,未必符合理想模型。因此在发布评估结果时,我会额外做一个盲去噪测试:把合成噪声数据集训练好的模型,直接拿到未参与训练的真实噪声显微图上做推理,观察纹理保留情况和伪影强度。

另外,如果做的是超分和去噪联合任务,不要先把噪声从 HR 上减掉再下采样。正确顺序应该是:HR 图先加噪声,再模糊下采样,得到带噪 LR。这样模型在超分的同时必须去噪,才能恢复出干净的高频细节。

4.3 显微图像中噪声的前置处理

在训练前,建议先统计一下数据集的噪声水平。简单的方法是选取图像中一块均匀背景区域,计算其灰度标准差。这个标准差可以作为高斯噪声强度的近似。如果标准差超过 10(8bit 图像),说明原图噪声不低,超分模型容易把噪声放大,此时需要在损失函数里加上全变分正则项。

我常用的损失函数组合是 L1 损失加 0.01 倍的全变分损失。L1 比 L2 对异常值更鲁棒,适合显微图像中存在的少量高亮杂质点。

5. 从 MATLAB 脚本迁移到 Python 工作流的三个坑

5.1 文件命名与排序陷阱

原始数据集里的文件名是93.png81.png这种三位数字,但顺序不是连续的。如果用 Python 的默认字符串排序,81.png会排在93.png后面,因为字符'8''9'小,但9381的比较结果没问题。真正麻烦的是如果你还有100.png,字符串排序会把100.png排到81.png前面,因为'1''8'小。

解决方法是读取文件名时提取数字部分排序:

import os files = os.listdir(hr_dir) files = sorted(files, key=lambda x: int(x.split('.')[0]))

这个细节会直接导致训练集乱序,进而影响随机种子和验证集划分的确定性。

5.2 Bicubic 退化在 OpenCV 与 MATLAB 的差异

MATLAB 的imresize和 OpenCV 的cv2.resize虽然都叫 bicubic,但插值核的系数并不相同。MATLAB 默认使用 keys 立方卷积核的变体,而 OpenCV 的INTER_CUBIC用的是不同的 a 参数。实测下来,对同一张 256×256 的图缩放到 64×64,两个库生成的 LR 像素值最大可以差到 3-5 个灰度级。

这对于训练影响不大,但如果你想和论文中的 PSNR 对比,必须保持一致。我建议用 scipy 的ndimage.zoomorder=3来模拟 MATLAB,或者干脆在 Python 里调用 MATLAB 引擎。如果只是日常实验,直接用 OpenCV 即可,但要在论文或博客里说明退化类型是 "bicubic (OpenCV)"。

5.3 显存不够时的最小裁剪策略

显微图像分辨率通常很大,动辄 2048×2048,如果直接把整图放进显卡做 4 倍超分,显存很容易不够。特别是现在大家还关注视频超分场景,比如 seedvr2 这类视频超分模型对显卡要求更高,因为视频帧在时间维度上增加了显存消耗。显微图像虽然只有单张,但裁剪策略同样重要。

我的做法是先把 HR 图切成 256×256 的小块,重叠 32 像素,推理时再拼接回去。重叠区域做加权平均,中心权重高,边缘权重低,这样可以避免拼接缝。如果你只有 8GB 显存,建议用下面的配置:

# 推理配置 patch_size = 128 overlap = 16 scale = 4 lr_patch_size = patch_size // scale

这样每一步推理只处理 128×128 的 HR 头,显存占用基本不到 2GB。如果你需要更高的重建质量,可以增大 patch_size 到 192,同时减少 batch size 到 1。

另外,如果你真的在同时处理多帧显微图像,比如一段焦平面扫描序列,可以参考视频超分的内存复用思路:把相邻帧共享的上下文缓存下来,只计算新增区域。这样能显著降低显存压力,但要注意显微图像序列往往存在漂移,直接用视频超分的对齐模块反而会引入伪影。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询