3. 医学影像预处理工程

在3D医学影像进入检测或分类网络之前,预处理决定了后续模型能否稳定收敛、能否跨设备泛化。原始DICOM或NIfTI数据往往存在体素间距不一致、灰度范围漂移、磁场偏置、噪声干扰以及层厚各向异性等问题。如果直接把这些数据送入网络,模型学到的可能是扫描仪参数而非解剖结构。因此,预处理工程的核心目标可以概括为:让不同来源、不同设备、不同协议的影像在几何空间和强度空间上趋于一致。

重采样:统一几何空间

重采样解决的是体素间距和图像尺寸不一致的问题。例如,某CT数据体素间距为0.7×0.7×1.5 mm,另一台设备为0.6×0.6×1.0 mm,若直接输入网络,同一解剖结构在不同样本中占据的体素数不同。常见做法是将所有数据重采样到统一间距,如1×1×1 mm各向同性体素。插值方式需要根据数据类型选择:CT等灰度连续图像常用三线性插值或B样条插值;分割标签必须使用最近邻插值,避免产生不存在的类别值。重采样后还需同步更新仿射矩阵,否则空间坐标会错位。

偏置场校正:消除低频强度不均

MRI中由于射频场不均匀,常出现同一组织在图像中心与边缘灰度不一致的现象,称为偏置场。N4ITK偏置场校正是一种常用方法,其基本思路是迭代估计一个平滑的低频乘性场,并将其从原图中去除。实际操作中通常先做颅骨剥离或掩膜,再在掩膜内估计偏置场,避免背景干扰。校正后的图像应表现为白质、灰质、脑脊液之间的灰度对比更均匀,而不是整体变亮或变暗。

去噪与各向异性处理

低剂量CT或高加速MRI常伴随噪声。去噪不是简单模糊,而是要在抑制噪声的同时保留边缘。非局部均值去噪和高斯滤波是常见选择,但高斯滤波容易过度平滑细小病灶。各向异性处理则针对层厚远大于层内分辨率的情况,例如层厚5 mm、层内0.5 mm的MRI。此时可通过插值将Z轴重采样到与XY轴接近的间距,但要注意:插值不能真正恢复丢失的层间信息,只能改善网络对三维结构的感知一致性。若层厚过大,应考虑在预处理阶段标记该样本质量,或在训练中采用各向异性增强策略。

强度标准化:统一灰度分布

强度标准化使不同样本的灰度分布可比。CT常用窗宽窗位截断,如脑窗取40 HU、窗宽80 HU,将灰度裁剪到[0,80] HU后再缩放到[0,1]。MRI没有绝对HU单位,常用Z-score标准化:对脑掩膜内体素计算均值和标准差,逐样本标准化。若直接对全图做Z-score,背景零值会拉低均值,导致脑组织对比度异常。因此,标准化前先做掩膜或前景提取非常关键。

3D医学影像预处理流水线:从原始体数据到标准化张量 原始体数据 DICOM / NIfTI 间距不一致 重采样 1×1×1 mm 三线性 / 最近邻 偏置场校正 N4ITK 掩膜内估计 去噪 非局部均值 保边平滑 各向异性 Z轴插值 层厚补偿 强度标准化 CT:窗宽窗位截断 → [0,1] 缩放 | MRI:脑掩膜内 Z-score 标准化 标准化3D张量 统一间距 · 统一尺寸 · 统一强度分布 关键检查点 • 仿射矩阵是否同步更新 • 分割标签是否用最近邻 • 偏置场是否在掩膜内估计 • 标准化是否排除背景零值 • 层厚过大是否标记质量 常见参数示例 • 目标间距:1.0×1.0×1.0 mm • CT脑窗:WL=40, WW=80 • MRI Z-score:掩膜内 μ,σ • N4:迭代次数 4 级 • 去噪:NLM h=0.05~0.1

工程实现中的顺序与依赖

预处理顺序并非随意排列。通常先做重采样统一几何空间,再做偏置场校正和去噪,最后做强度标准化。原因在于:偏置场估计依赖空间平滑性,若先重采样到各向同性,偏置场估计更稳定;去噪若在标准化之后进行,可能破坏已统一的灰度分布。各向异性处理可与重采样合并,但若层厚差异极大,建议单独评估是否值得插值。

以下是一个可参考的Python预处理片段,展示NIfTI数据的重采样与Z-score标准化核心逻辑:

import nibabel as nib
import numpy as np
from scipy.ndimage import zoom

# 读取数据
img = nib.load("case_001.nii.gz")
data = img.get_fdata()
zooms = img.header.get_zooms()  # 原始体素间距

# 重采样到 1×1×1 mm
target = (1.0, 1.0, 1.0)
factors = [z / t for z, t in zip(zooms, target)]
resampled = zoom(data, factors, order=1)  # 三线性插值

# 脑掩膜内 Z-score 标准化
mask = resampled > np.percentile(resampled, 20)  # 示例掩膜
mu = resampled[mask].mean()
sigma = resampled[mask].std()
normalized = (resampled - mu) / (sigma + 1e-8)

# 裁剪到合理范围
normalized = np.clip(normalized, -5, 5)
print("输出尺寸:", normalized.shape, "均值:", normalized[mask].mean())
提示:标准化参数(均值、标准差、窗宽窗位)应基于训练集统计并固定,验证集和测试集直接复用,避免数据泄漏。若每个样本单独做Z-score,则属于逐样本标准化,适用于MRI;若使用全局统计量,则更接近CT的HU标准化思路。
注意:各向异性插值不能恢复真实层间信息。若原始层厚为5 mm,插值到1 mm后,Z轴方向仍存在模糊。此时可在训练中引入各向异性数据增强,或在网络设计中采用各向异性卷积核,而不是仅依赖预处理。

结果判断与质量检查

预处理完成后,建议从三个层面检查:几何层面,确认所有样本体素间距、尺寸、方向一致,仿射矩阵无异常;强度层面,确认前景区域灰度分布合理,无过曝或过暗;结构层面,确认偏置场校正后白质灰度均匀,去噪后边缘仍清晰。若发现某样本标准化后均值偏离0超过1个标准差,应回溯检查掩膜是否包含大量背景或偏置场估计失败。

预处理不是一次性脚本,而是需要随数据分布变化持续监控的工程环节。建议将每个样本的预处理参数、输出统计量和质量标记记录到清单中,便于后续排障和模型复现。