⌈ 传知代码 ⌋ 基于多模板配准的心腔分割算法

96 阅读5分钟

前情提要

本文是传知代码平台中的相关前沿知识与技术的分享~

接下来我们即将进入一个全新的空间,对技术有一个全新的视角~

本文所涉及所有资源均在传知代码平台可获取

以下的内容一定会让你对AI 赋能时代有一个颠覆性的认识哦!!!

以下内容干货满满,跟上步伐吧~


💡本章重点

  • 基于多模板配准的心腔分割算法

🍞一. 概述

本文复现论文 Automatic Whole Heart Segmentation in CT Images Based on Multi-atlas Image Registration[1] 提出的心腔分割算法。

整个心脏子结构的准确分割、建模和分析对于临床应用的开发非常重要。然而,对全部心脏子结构的分割十分具有挑战性,且目前仍然依赖手动操作。为了解决这一难题,该论文提出了一种基于多模板图像配准的自动全心分割算法。

论文所提出的方法对患者CT图像中心脏部分的七个子结构进行图像分割。子结构包含:左心室腔、右心室血液腔、左心房腔、右心房血液腔、左心室心肌、从主动脉瓣到心房上部水平的上行主动脉干、从肺动脉瓣到分叉点的肺动脉干。

论文提出的算法主要包含三个步骤:感兴趣区域获取、精确分割、结果融合。

该论文基于多模态全心脏分割挑战赛(MM-WHS 2017)数据集进行测试。该数据集包含:训练数据(20张CT图像)和测试数据(40张CT图像),且所有数据均为从真实的临床环境中获取。其中每张CT图像附带了一张标记了七个心脏子结构的标签图像。


🍞二. 算法原理

论文提出的算法主要包含三步:

  • 第一步,获取感兴趣区域ROI(Region of Interest)。首先,将患者CT图像与模板图像统一下采样为低清晰度图像;然后,使用仿射配准(Affine registration)将患者图像与模板图像配准;最后,使用输出的配准参数对模板的心脏标签图像进行变换,获取ROI。

  • 第二步,对心脏进行精确分割。首先,利用ROI对原始的患者CT图像进行裁剪;然后,基于两步配准(仿射配准、B-样条配准)将裁剪后图像与模板图像进行配准;最后,使用输出的配准参数对模板的各标签图像进行变换,获取对患者CT图像中心脏的精确分割。

  • 第三步,筛选模板并集成结果。首先,基于两步配准中仿射配准结果的互信息MI(Mutual Information)对模板进行排序和过滤,并选择一定数量的模板参与后序步骤;然后,重新使用B-样条非刚性配准获取对患者CT图像中心脏的精确分割;最后,将各个模板的互信息作为权重,利用投票对分割结果进行融合,获取最终结果。


🍞三.核心逻辑

由于官方数据集并没有提供全心脏标签,原文也未对全心脏标签的获取方法进行解释,故本文删去了原算法的裁剪步骤,具体的核心逻辑如下所示:

from utils import config_read
from heart_seg import affine_registration, bspline_registration, label_transform
import os
import itk
import numpy as np
from sklearn.metrics import mutual_info_score
from datetime import datetime

if __name__ == "__main__":
    # 读取配置
    args = config_read("./config.json")
    # 新建结果目录
    result_path = os.path.join(args.result_path, datetime.now().strftime("%Y%m%d_%H%M%S"))
    if not os.path.exists(result_path):
        os.mkdir(result_path)
    # 测试样本地址
    test_path_list = [os.path.join(args.test_path, "ct_test_%s_image.nii.gz"%str(i+2001)) for i in range(args.test_num)]
    for test_id in range(len(test_path_list)):
        # 读取测试图像
        test_path = test_path_list[test_id]
        test_image = np.asarray(itk.imread(test_path, itk.F))
        # 训练样本地址
        train_path_list = [os.path.join(args.train_path, "ct_train_%s_image.nii.gz"%str(i+1001)) for i in range(args.train_num)]
        atlas_mi = []
        for train_path in train_path_list:
            # 读取训练图像
            train_image = np.asarray(itk.imread(train_path, itk.F))
            # 利用仿射配准对齐患者CT与模板图像
            train_image_affine, _ = affine_registration(test_image, train_image)
            # 计算患者图像与变换后模板图像的互信息
            mi = mutual_info_score(test_image.ravel(), train_image_affine.ravel())
            atlas_mi.append(mi)
        # 筛选模板
        choosed_ids = sorted(range(len(atlas_mi)), key=lambda i: atlas_mi[i], reverse=True)[:args.atlas_num]
        logits = np.zeros((test_image.shape[0], test_image.shape[1], test_image.shape[2], 7), dtype=np.float32)
        for id in choosed_ids:
            train_image = np.asarray(itk.imread(train_path_list[id], itk.F))
            # 利用B-样条配准对齐患者CT与模板图像
            _, transform_parameters = bspline_registration(test_image, train_image)
            # 读取模板标签
            label_image = np.asarray(itk.imread(os.path.join(args.train_path, "ct_train_%s_label.nii.gz"%str(id+1001)), itk.F))
            # 利用B-样条配准结果的变换参数对模板图像的子结构标签图像进行变换,获得对患者心脏的精确分割。
            transformed_labels = label_transform(label_image, transform_parameters)
            # 利用之前获取的互信息作为权重,以投票的方式融合各个模板的精确分割结果。
            logits = logits + transformed_labels * atlas_mi[id]
        predicted = np.argmax(logits, dim=-1)
        # 存储最终的分割结果
        np.save(os.path.join(result_path, "ct_test_%s_predicted.npy"%str(test_id+2001)), predicted)

使用方式

  • 代码的运行环境可通过如下命令进行配置:
pip install numpy
pip install itk-elastix
pip install scikit-learn
pip install matplotlib
pip install tqdm
  • 解压附件压缩包并进入。如果是Linux系统,请使用如下命令:
unzip Multi-Atlas-Registration.zip
cd Multi-Atlas-Registration
  • 实验数据可通过如下链接进行下载:

    • 训练数据图像、训练数据标签、测试数据图像下载链接见附件READ.ME

    • 测试数据标签下载链接见附件READ.ME(非必要)

  • 将下载好的数据放置在Multi-Atlas-Registration/dataset目录下的合适位置,完整的目录结构应当如下图所示:

Multi-Atlas-Registration
│
├──datasets
│    │
│    ├── ct_train
│    │   ├── ct_train_1001_image.nii.gz
│    │   ├── ct_train_1001_label.nii.gz
│    │   ├── ct_train_1002_image.nii.gz
│    │   ├── ct_train_1002_label.nii.gz
│    │   └── ...
│    │
│    └── ct_test
│        ├── ct_test_2001_image.nii.gz
│        ├── ct_test_2002_image.nii.gz
│        └── ...
│
├──results
│    │
│    └── example
│        ├── example_image.nii.gz
│        └── example_predicted.npy
├──config.json
├──heart_seg.py
├──utils.py
├──main.py
├──example.py
└──README.md

🍞四.效果演示

配置环境并下载示例后,运行附件目录中的example.py脚本,效果如下:

在这里插入图片描述


🫓总结

综上,我们基本了解了“一项全新的技术啦” :lollipop: ~~

恭喜你的内功又双叒叕得到了提高!!!

感谢你们的阅读:satisfied:

后续还会继续更新:heartbeat:,欢迎持续关注:pushpin:哟~

:dizzy:如果有错误❌,欢迎指正呀:dizzy:

:sparkles:如果觉得收获满满,可以点点赞👍支持一下哟~:sparkles:

【传知科技 -- 了解更多新知识】