基于PaddleSeg实现MR头部矢状位上快速自动定位

点击左上方蓝字关注我们

项目背景

在日常放射科工作中对患者进行磁共振头部检查时,扫描头部轴位,规范标准要求扫描轴位像,需要在矢、冠、轴位定位像上进行定位。冠、轴位像只需要左右对称即可。但是在矢状位定位像上,需要平行胼胝体的前后缘连线(如图)。目前一部分品牌的磁共振机器已经实现自动定位的功能。

磁共振成像,有个特点,时间长。假如确定好扫描范围和参数后,要扫描结束后才能阅览图像。阅览图像时发现范围定位错误或者参数设置错误,那只能重新扫描。而磁共振成像,每一个成像序列都需要1到几分钟不等。因上述错误导致重新扫描,需要的时间成本是很大的,也增加了患者的负担。因此自动定位可以减少人为的错误并加快检查速度,节约时间。

因此本项目是基于PaddleSeg分割开发套件实现类似的自动定位功能。

图1 磁共振颅脑扫描规范

这个项目主要分割颅脑中的胼胝体器官。大脑主要由皮质(灰质)和白质组成,而胼胝体作为最大的连合纤维,连接着左右大脑半球的皮质。胼胝体位于大脑正中矢状切面上,形态上类似弓形,如图2所示。

图2 胼胝体的解剖位置

本项目基于PaddleSeg开发。PaddleSeg是基于飞桨PaddlePaddle开发的端到端图像分割开发套件,涵盖了高精度轻量级等不同方向的大量高质量分割模型。通过模块化的设计,提供了配置化驱动API调用两种应用方式,帮助开发者更便捷地完成从训练到部署的全流程图像分割应用。这个项目主要用到的是API调用的方式。

项目使用PaddleSeg实现的BiSeNetV2网络结构,分割MR头部矢状位上的胼胝体。最终,胼胝体的分割结果miou达到了0.8696。然后,我们将通过OpenCV获取胼胝体的轮廓,得到最左、右的像素点位置,并计算旋转的角度。根据角度得到旋转的定位范围框。

项目在AI Studio上已经公开,并提供了数据集在内的完整路径。Fork之后可以直接运行,相关链接为:

https://aistudio.baidu.com/aistudio/projectdetail/1993321

https://github.com/paddlepaddle/paddleseg

最终效果如图3所示。

图3 最终效果

网络结构介绍

此项目使用PaddleSeg 的API接口,进行数据增强、Loss、和训练和推理,本文主要针对以上步骤进行介绍。

因为自动定位需要速度够快,并且有一定的准确性。因此,选择使用BiSeNetV2 网络结构。BiSeNetV2 网络结构在Cityscapes测试集上获得了72.6%的平均IoU,在一张NVIDIA GeForce GTX 1080Ti卡上获得了156 FPS的速度,如图4所示。使用此分割网络很适合“实时”定位任务。

目前提高语义分割的运行速度一般有以下方法:

  1. 可以通过缩小输入图像的大小来实现,但是会失去部分空间信息。

  2. 通过对减少网络通道数量加快处理速度,但是弱化网络提取特征的能力。

这些提速的方法会丢失很多空间信息,从而导致精准度下降。为了防止空间信息的丢失,有些网络会采用U型结构来恢复空间信息。但是U型结构会降低速度。因此BiSeNetV2提出“双边分割”。在速度和准确性之间进行了很好的权衡。

BiSeNetV2结构设计上,实现细节分支和语义分支,并设计一个引导聚合层来融合两个分支的特征。还设计了一种增强训练策略。只在训练中使用,在推理过程中不增加任何代价,BiSeNetV2整体网络结构,如图E所示。

BiSeNetV2的细节分支,使用宽通道和进行三次下采样卷积,来提取低语义空间信息生成高分辨率特征。在语义分支,使用窄通道和深度卷积来增强感受野和获取丰富的上下文信息。由于采用“双边”分支,需要把两支分支进行融合。但是细节分支和语义分支的特征大小不一致,还有细节分支是低级语义信息,语义分支是高级语义信息,简单的组合这两者信息,得不到有效利用。

因此BiSeNetV2提出双边引导的聚合层融合两个分支的信息,如图6。作者为了进一步不影响推理速度的情况下,提出一种增强训练策略(SegHead),使用在语义分支的不同位置上,如图5的Booster。最终在Cityscapes测试集上获得了72.6%的平均IoU,在一张NVIDIA GeForce GTX 1080Ti卡上获得了156 FPS的速度。

图4 BiSeNetV2 在Cityscapes测试集上推理精度和速度

图5 BiSeNet V2的整体网络结构

图6 BiSeNetV2的双边引导聚合层(Bilateral Guided Aggregation)

使用PaddleSeg套件搭建BiSeNetV2 只需要两行代码。代码如下:

from paddleseg.models import BiSeNetV2
model = BiSeNetV2(num_classes=2,
                 lambd=0.25,
                 align_corners=False,
                 pretrained=None)

lambd这个参数用来控制语义分支中前两者的通道数,使语义分支是轻量的。作者论文中提到,加大lambda可以提高精度,但是会损失一定推理时间。align_corners这个参数控制使用插值时是否将输入和输出张量的4个角落像素的中心对齐,并保留角点像素的值。

数据处理和增强

从约600个健康的患者的头部MRT1轴位NiFit格式数据,随机挑选120例。使SimpleITK读取数据,获取120张正中位置的矢状位MR图像,并保存成jpg格式图像。并使Labelme对胼胝体器官的进行标注。把数据集分成8:2,作为训练集和验证集并生成train.txt和val.txt搭建Dataset时使用,如图7。

注:数据来源https://brain-development.org/ixi-dataset/

图7 数据的处理流程

结合实际情况,不同的矢状定位图的旋转角度相差巨大。除了增加了随机水平翻转和随机模糊、随机对比度、明亮度等数据增强策略。重要的使用较大的角度旋转来增加数据的多样性。通过PaddleSeg的API(paddleseg.transform),可以快速实现数据增强策略。预览通过数据增强后的图片数据,如图8所示。

import paddleseg.transforms as T
from paddleseg.datasets import Dataset

#数据增强部分
train_transforms = [
    T.RandomHorizontalFlip(),#水平翻转
    T.RandomDistort(),#随机对比度,颜色等变化
    T.RandomRotation(max_rotation = 25,im_padding_value=(0,0,0), label_padding_value = 0),#随机旋转
    T.Resize(target_size=(512, 512)),
    T.Normalize()
]

训练之前,需要通过API(paddleseg.datasets)快速构建可迭代的训练数据装载器和验证集/测试集数据装载器。只需要传入包含origin和label文件路径的train.txt文件、数据增强策略、分类类别和数据存放路径,即可构建高效的数据装载器。

train_dataset = Dataset(
    transforms = train_transforms,
                  dataset_root = dataset_root,
                  num_classes = 2,
                  train_path  = train_path,
                  mode = 'train'
                  )

图8经过数据增强的原图和Mask

模型训练

开始训练前,还需要定义损失函数,PaddleSeg提供多种损失函数的选择。只需要通过API(paddleseg.models.losses)调用就能实现。因为BiSeNetV2  采用增强训练策略(SegHead)。一共使用了5个(SegHead),所以配置损失函数的时候,数量为5。

#构建优化器,和loss
from paddleseg.models.losses import CrossEntropyLoss
import paddle
losses = {}
losses['types'] = [CrossEntropyLoss()] * 5
losses['coef'] = [1]* 5

因为PaddleSeg动态图版本开始训练模型只需要一行代码,调用API(paddleseg.core.train)即可开始训练,训练期间还可以通过VisualDL可视化训练期间的Loss、ACC、IOU等结果,如图9所示。比起静态图组网,此种方式大幅度降低了代码量。

#开始训练
from paddleseg.core import train
train(
    model=model,
    train_dataset=train_dataset,
    val_dataset=val_dataset,
    optimizer=optimizer,
    save_dir='Myoutput',
    iters=4800,
    batch_size=8,
    save_interval=120,
    log_iters=24,
    num_workers=0,
    losses=losses,
use_vdl=True)

图9 VisualDL可视化训练期间的Loss

处理推理结果实现快速定位

我们可以调用PaddleSeg的API接口(paddleseg.core.predict)进行推理。同样地,我们也可以自定义推理接口,只需要导入PaddleSeg模型,加载最优模型训练结果,设置模型为eval模式,传入需要预测的胸片数据,即可进行推理。

model = BiSeNetV2(num_classes=2)
model_path = '/home/aistudio/Myoutput/best_model/model.pdparams'
para_state_dict = paddle.load(model_path)
model.set_dict(para_state_dict)
model.eval()
data = np.expand_dims(data,axis=0).repeat(3,axis=0)
data = np.transpose(data, (1,2,0))
data,_ = transforms(data)
data = data[np.newaxis, ...]
data = paddle.to_tensor(data)
output = model(data)[0].numpy()
output = np.argmax(output,axis=1)
output = np.squeeze(output)

得到推理结果,通过OpenCV对结果进一步处理。先提取轮廓,然后根据提取出来的轮廓得到胼胝体的最左边和最右边的像素点坐标。根据左、右两点坐标求得两点的中心坐标。通过反正切函数求得最左边与中心点坐标连线与水平方向(X轴)的夹角,整体流程如图10所示。

points = list() #用来保存坐标点
#对预测的结果进行阈值分割
ret, binary = cv2.threshold(output,0,255,cv2.THRESH_BINARY)
#获取轮廓的所有坐标点
contours, hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
for p in contours[0]:
    points.append(p.tolist()[0])
#根据坐标x轴从小到大排序
points = sorted(points)
#得到最左边的坐标点和最右边的坐标点
left_point = points[0] 
right_point = points[-1]
#计算最左和最右两个坐标点之间的中间坐标
center_point = [int((right_point[0] - left_point[0])/2)+left_point[0],
                int((right_point[1] - left_point[1])/2)+left_point[1]]
#计算最左边的坐标点和中间坐标点连线  与 X轴之间的夹角
dx1 = left_point[0] - center_point[0]
dy1 = left_point[1] - center_point[1]
#atan2函数计算线段与X轴夹角(弧度)
angle = math.atan2(dy1, dx1)

然后根据上述的中心坐标为中心创建一个矩形框。用来模拟磁共振在定位图上的扫描范围框。根据已得的角度,通过以下代码计算矩形框每个坐标经过旋转后的坐标。在原图上进行绘制旋转后的矩形框。即可快速自动实现平行胼胝体的前后缘的定位。具体实现代码这里不做详细展示,读者可以访问AI Studio项目查看。

rotationx = (x  - centerx)* math.cos(angle) - (y - centery)* math.sin(angle) + centerx
rotationy = (x  - centerx)* math.sin(angle) + (y - centery)* math.cos(angle) + centery

图10 项目流程图

总结

从观察到需要解决的问题,到思考如何解决问题,开始收集数据并标记数据,搭建Dataset、构建网络、训练、参数调优,到最后通过对推理结果进行处理。整个项目只要准备好数据和知道怎样处理推理结果,中间的分割部分,例如网络的搭建和训练代码。只需要结合PaddleSeg API很容易搭建一个完整的分割任务,实现想要的效果。

参考文献:

Yu, Changqian, et al. "BiSeNetV2: Bilateral Network with Guided Aggregation for Real-time Semantic Segmentation"(https://arxiv.org/abs/2004.02147)

飞桨开发者说直播

主题:基于PaddleSeg实现MR头部矢状位上快速自动定位

分享人:冯嘉骏,飞桨开发者技术专家 PPDE

如在使用过程中有问题,可加入官方QQ群进行交流:793866180。

如果您想详细了解更多飞桨的相关内容,请参阅以下文档。

·飞桨官网地址·

https://www.paddlepaddle.org.cn/

·飞桨开源框架项目地址·

GitHub: https://github.com/PaddlePaddle/Paddle 

Gitee: https://gitee.com/paddlepaddle/Paddle

????长按上方二维码立即star!????

飞桨(PaddlePaddle)以百度多年的深度学习技术研究和业务应用为基础,集深度学习核心训练和推理框架、基础模型库、端到端开发套件和丰富的工具组件于一体,是中国首个开源最早、技术领先的产业级深度学习平台。飞桨企业版针对企业级需求增强了相应特性,包含零门槛AI开发平台EasyDL和全功能AI开发平台BML。EasyDL主要面向中小企业,提供零门槛、预置丰富网络和模型、便捷高效的开发平台;BML是为大型企业提供的功能全面、可灵活定制和被深度集成的开发平台。

END

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值