返回列表

17th Place Solution: An Alternative Rectification Workflow

686. PhysioNet - Digitization of ECG Images | physionet-ecg-image-digitization

开始: 2025-10-21 结束: 2026-01-22 医学影像分析 数据算法赛
第 17 名解决方案:一种替代的校正工作流程

第 17 名解决方案:一种替代的校正工作流程

作者: MaxChen303 (MASTER)
发布时间: 2026 年 1 月 24 日
竞赛排名: 17

感谢组织者和 Kaggle 工作人员举办这场有趣的比赛。我还要感谢 @hengck23 提出的多阶段流水线想法。我的解决方案遵循该框架,但使用了不同的图像校正实现方法,这是我想在此分享的主要部分。

解决方案总结

  • 单折模型流水线(无集成)。
  • 最终提交运行时间大约 < 1.5 小时。
  • 硬件:所有模型均在单个 RTX 4080 GPU (16GB) 上训练。

流水线阶段:

  1. 单应性变换 (非机器学习)
  2. 网格级校正
  3. 线条强度分割
  4. 信号提取 (从预测的强度图中)

1. 单应性变换 (Homography Transformation)

似乎许多团队使用机器学习模型来解决这一阶段,而我实施了一个仅利用 OpenCV 的解决方案:

  • 关键点检测: 我掩蔽了一个通用模板,并从模板和目标图像中检测了 SIFT 关键点。图表顶部的文本标题实际上对对齐很有用。
  • 匹配: 使用 RANSAC 对关键点进行匹配和过滤,针对 warped paper 设置了较大的像素误差阈值。
  • 对齐: 应用生成的单应性变换 (cv2.perspectiveTransform) 将图像对齐到模板平面,保持一致的尺度。

模板掩膜

Template Mask
检测到的关键点与匹配 叠加模板网格点的单应性校正图像
Detected Keypoints Homography rectified

2. 网格级校正 (Grid-Level Rectification)

此阶段侧重于在亚像素级别检测网格点并将其与模板网格匹配:

  • 模型与推理: 我训练了一个分割模型来预测网格点概率。在推理过程中,我使用 monai 滑动窗口函数在原始分辨率下进行预测,随后通过加权局部概率导出坐标以实现亚像素精度。
  • 泛化: 对 '0001' 图像进行强增强使模型能够很好地泛化到其他类型。因此,标签 simply 从 '0001' 集合中提取为整数网格点,无需进一步生成标签。
  • 过滤: 我还预测了一个线条掩膜概率通道。这用于过滤掉经常出现在信号线附近的假阳性网格点。
  • 网格组装: 单应性变换后,许多点与模板紧密对齐。我利用这些点构建了一个结构化网格并相应地匹配检测到的点。
  • 校正: 使用 PyTorch 的 grid_sample 和双线性插值执行最终的非刚性 warp。
Predicted Gridpoints Filter Gridpoints Grid Alignment

3. 线条像素分割 (Line Pixel Segmentation)

  • 真值 (Ground Truth): 掩膜由修改后的 ecg-image-kit 绘图函数生成,其中概率基于像素强度计算。
  • 训练: 我在网格校正后的图像上使用 512 像素窗口训练了分割模型。
  • 推理: 应用滑动窗口预测来处理完整的 (1700 x 2200) 图像。

4. 信号提取 (Signal Extraction)

我构建了一个回归模型,直接从分割掩膜预测亚像素级坐标。

模型架构

输入:(B, 1440, 1968)                   # [Batch, Height, Width]
---------------------------------------------------------------------------
1. 垂直 2D 卷积编码器 (折叠高度)
   (B, 1, 1440, 1968)  -->  (B, 512, 1968)  # 高度被压缩为 1
2. 带有 ROPE 的 CNN & Transformer (混合上下文)
   (B, 512, 1968)      -->  (B, 512, 1968)  # 时间/导联混合 (形状不变)
3. 细化 (跳跃连接)
   (B, 1024, 1968)     -->  (B, 512, 1968)  # 合并原始 + 混合特征
4. 上采样 (双倍宽度)
   (B, 512, 1968)      -->  (B, 256, 3936)  # Pixel Shuffle
5. 热力图 & Soft-Argmax (最终投影)
   (B, 256, 3936)      -->  (B, 4, 256, 3936) # 拆分为 4 个导联 & 256 个 Bin
---------------------------------------------------------------------------
最终输出:(B, 4, 3936)               # [Batch, Leads, Y-Coordinates]

训练与性能

使用了两种损失函数:预测 y 坐标的 MSE 损失 和转换信号值的 SNR 损失

  • 预训练: 模型在来自 PTB-XL 数据集的真值掩膜上进行了预训练。当使用竞赛真值线条强度作为输入时,验证 SNR 达到了 30dB。此阶段在单个 GPU 上收敛耗时约 10 小时。
  • 微调: 我在预测的线条概率掩膜上对模型进行了微调。微调仅需几个 epoch 就开始过拟合。
  • 结果: 微调期间本地验证性能降至 ~25-26dB,主要受限于上一阶段预测的概率掩膜的质量。
同比赛其他方案