3. 病理图像预处理工程
全切片图像(WSI)动辄数万×数万像素,一张 40× 的切片在磁盘上常达 1~3 GB。若把整张图直接送入训练或推理,绝大部分算力会消耗在白色玻璃背景上,而真正含诊断信息的组织区域往往只占 20%~60%。因此,预处理工程的核心目标可以概括为一句话:用尽可能低的成本,把“有效组织像素”从“背景、伪影、低质量区域”中分离出来,并给出可追溯的质量标签。本节围绕组织区域分割、背景去除、伪影检测与质量控制四条链路,讲清自动化实现的关键参数与判断依据。
一、组织区域分割:从缩略图到掩膜
工程上几乎不会在全分辨率上做组织分割,而是先在低倍缩略图上完成,再把掩膜映射回原图坐标。典型流程是:读取 WSI 的 level 0 尺寸与各层下采样倍率,取一个约 1/32 或 1/64 的层级(例如 40× 切片对应约 1.25×),得到一张几千像素宽的缩略图。随后做两件事:一是颜色空间转换,把 RGB 转到 HSV 或 Lab,利用饱和度 S 与亮度 V 的差异区分组织与玻璃;二是阈值化,常用 Otsu 自动阈值或固定阈值组合。
一个可复现的示例参数是:在 HSV 空间取 S 通道,先做 5×5 高斯模糊抑制噪声,再用 Otsu 得到阈值 t,若 S > t 判为候选组织;同时用 V 通道排除过暗区域(如 V < 30 视为墨迹或阴影)。得到二值图后,用形态学开运算(核 7×7)去掉孤立噪点,用闭运算(核 15×15)填补组织内部的小孔洞,最后保留面积大于缩略图总面积 0.5% 的连通域,其余视为碎片丢弃。这样得到的掩膜再按倍率放大回 level 0,即可用于后续切块。
需要注意坐标约定:WSI 的 (0,0) 通常位于左上角,x 向右、y 向下,所有掩膜、切块坐标都沿用这一约定,避免后续拼接时出现镜像或偏移。
二、背景去除与切块策略
背景去除不是简单“把白色删掉”,而是决定哪些切块进入数据集。常见做法是在掩膜上以固定步长滑动窗口,例如 256×256 像素、步长 128(50% 重叠),逐块统计组织像素占比。占比低于阈值(如 30%)的块直接丢弃;占比在 30%~60% 的块保留但打上 low_tissue 标签,训练时可用于难例挖掘;占比高于 60% 的块作为常规样本。若某块组织占比超过 95% 且四周无空白,可标记为 dense,适合高倍放大训练。
重叠切块会带来重复样本,需要在采样阶段做去重或降权。一个实用做法是:对同一张切片,按块中心坐标做网格聚类,每个网格只保留组织占比最高的块,其余以 0.3 的权重参与训练。这样既保留边界信息,又避免模型反复看到几乎相同的图像。
三、伪影检测:笔迹、气泡、折叠与失焦
病理切片常见伪影包括:标记笔笔迹(蓝、绿、黑)、封片气泡、组织折叠、刀痕、灰尘以及失焦模糊。自动化检测通常分两步:先做颜色异常检测,再做纹理/清晰度检测。
笔迹检测可利用颜色先验:蓝色笔迹在 HSV 中 H 约 200°~240°、S 较高;绿色笔迹 H 约 90°~150°。对每个切块统计这些色相区间的像素比例,超过 5% 即标记 pen_mark。气泡表现为局部高亮、低饱和的圆形区域,可用 V > 230 且 S < 20 的连通域面积占比判断,超过 3% 标记 bubble。折叠区域则表现为局部对比度骤降、纹理方向紊乱,可用拉普拉斯方差(Laplacian variance)衡量:若某块方差低于全片组织块中位数的 0.4 倍,标记 fold 或 blur。
失焦检测更直接:对每个切块计算 Tenengrad 梯度能量或 Brenner 梯度,若低于阈值则判为失焦。示例阈值可设为全片组织块梯度中位数的 0.5 倍。所有伪影标签都应写入切块元数据,而不是直接删除,便于后续按需过滤或做鲁棒性实验。
四、质量控制:把标签变成可执行的过滤规则
质量控制的产出不是“好/坏”二分类,而是一组可组合的标签与分数。建议每个切块至少记录:组织占比 tissue_ratio、平均饱和度 mean_sat、拉普拉斯方差 lap_var、笔迹比例 pen_ratio、气泡比例 bubble_ratio、是否边缘 edge_flag。基于这些字段,可以定义分级规则:
| 等级 | 条件(示例) | 用途 |
|---|---|---|
| Q1 优质 | tissue_ratio ≥ 0.6,lap_var ≥ 中位数,pen_ratio < 0.01,bubble_ratio < 0.01 | 训练主集、验证集 |
| Q2 可用 | tissue_ratio ≥ 0.3,pen_ratio < 0.05,bubble_ratio < 0.03 | 训练集,可降权 |
| Q3 受限 | 存在 pen_mark / bubble / fold 之一,或 lap_var 偏低 | 仅用于鲁棒性测试 |
| Q4 丢弃 | tissue_ratio < 0.3,或严重失焦、大面积笔迹 | 不进入数据集 |
工程实现上,建议把上述规则写成配置文件而非硬编码,例如用 YAML 描述阈值,预处理脚本读取后逐块计算并输出 CSV/Parquet 清单。清单中每行对应一个切块,包含切片 ID、坐标、倍率、各指标与最终等级。这样当模型效果异常时,可以快速回溯是数据质量问题还是模型问题。
最后,预处理链路的输出应包含三样东西:切块图像(或坐标索引)、逐块质量清单、以及一份可复现的参数配置。三者缺一不可——只有图像没有清单,无法追溯;只有清单没有配置,无法复现。把这三者作为预处理工程的交付物,后续训练与验证才有稳定的数据基础。