🏡作者主页:点击!
🤖编程探索专栏:点击!
⏰️创作时间:2024年11月18日20点09分
神秘男子影,
秘而不宣藏。
泣意深不见,
男子自持重,
子夜独自沉。
论文链接
点击开启你的论文编程之旅https://www.aspiringcode.com/content?id=17102812998312
概述
本文复现论文 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 datetimeif __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)
以上代码仅作展示,更详细的代码文件请参见附件。
效果演示
配置环境并下载示例后,运行附件目录中的example.py脚本,效果如下:
使用方式
- 代码的运行环境可通过如下命令进行配置:
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
- 为了节约时间,我提供了一个已完成分割的测试样例(请从附件下载)并放到
results/example/
目录下。若想要查看它,请运行如下命令:
python example.py
- 如果希望测试完整的算法(时间很长),请运行如下命令:
python main.py
- 结果将保存在目录
Multi-Atlas-Registration/results
下,并以程序开始的时间(年月日_时分秒)作为名称。 - 如果希望使用自己的文件路径或改动其他实验设置,请在文件
Multi-Atlas-Registration/config.json
中修改对应参数。以下是参数含义对照表:
参数名 | 含义 |
train_path | 训练(模板)图像、标签目录 |
test_path | 测试(患者CT)图像目录 |
train_num | 训练图像数 |
test_num | 测试图像数 |
result_path | 结果存储目录 |
example_path | 样例目录 |
atlas_num | 筛选模板数 |
(以上内容皆为原创,请勿转载)
参考文献
[1] Yang G, Sun C, Chen Y, et al. Automatic whole heart segmentation in CT images based on multi-atlas image registration[C]//International Workshop on Statistical Atlases and Computational Models of the Heart. Cham: Springer International Publishing, 2017: 250-257.
成功的路上没有捷径,只有不断的努力与坚持。如果你和我一样,坚信努力会带来回报,请关注我,点个赞,一起迎接更加美好的明天!你的支持是我继续前行的动力!"
"每一次创作都是一次学习的过程,文章中若有不足之处,还请大家多多包容。你的关注和点赞是对我最大的支持,也欢迎大家提出宝贵的意见和建议,让我不断进步。"
神秘泣男子