使用SimpleITK进行3D图像连通域分析

一、简介

本文叙述了使用SimpleITK进行3D医疗图像连通域分析的方法。(相邻的像素值视为同一个连通域,不区分像素值)

非医疗图像需要先封装为SimpleITK.Image,或者使用scikit-image

二、SimpleITK连通域分析

SimpleITK库用于处理医疗图像(nii、nii.gz、mhd等格式),包含进行连通域分析的相关类及方法。

本文以获取最大连通域为例,按步骤描述,完整代码在本节末尾

上图所示为3D二值图像,包含多个连通域,我们需要过滤掉除体积最大之外的其他连通域。

1.首先实例化进行连通域划分的类并处理图像

# ConnectedComponentImageFilter类,用于连通域划分
cc_filter = sitk.ConnectedComponentImageFilter()
cc_filter.SetFullyConnected(True)
output_mask = cc_filter.Execute(itk_mask)  # 执行连通域划分,输出为sitk.Image格式

进行连通域划分后,output_mask可视化如下图

共划分为12个连通域,连通域之间label互不相同。

其中,SetFullyConnected(True)个人理解为设置为26连通。

如果设置为False,连通域的数量会由12上升到171,output_mask如下图

 

该方法原文档描述如下:

Set/Get whether the connected components are defined strictly by face connectivity or by face+edge+vertex connectivity.

2. 为了获取各个连通域的体积属性(体素个数),实例化相关类

# LabelShapeStatisticsImageFilter类,用于获取各标签形状属性
lss_filter = sitk.LabelShapeStatisticsImageFilter()
lss_filter.Execute(output_mask)  # 分析连通域

3. 根据连通域体积大小进行过滤

num_connected_label = cc_filter.GetObjectCount()  # 获取连通域个数

area_max_label = 0  # 最大的连通域的label
area_max = 0

# 连通域label从1开始,0表示背景
for i in range(1, num_connected_label + 1):
    area = lss_filter.GetNumberOfPixels(i)  # 根据label获取连通域体积
    if area > area_max:
        area_max_label = i
        area_max = area

np_output_mask = sitk.GetArrayFromImage(output_mask)
res_mask = np.zeros_like(np_output_mask)
res_mask[np_output_mask == area_max_label] = 1

处理结果如图,只保留了最大的连通域

完整代码

import numpy as np
import SimpleITK as sitk


def max_connected_domain(itk_mask):
    """
    获取mask中最大连通域
    :param itk_mask: SimpleITK.Image
    :return:
    """
    
    cc_filter = sitk.ConnectedComponentImageFilter()
    cc_filter.SetFullyConnected(True)
    output_mask = cc_filter.Execute(itk_mask)

    lss_filter = sitk.LabelShapeStatisticsImageFilter()
    lss_filter.Execute(output_mask)

    num_connected_label = cc_filter.GetObjectCount()  # 获取连通域个数

    area_max_label = 0  # 最大的连通域的label
    area_max = 0

    # 连通域label从1开始,0表示背景
    for i in range(1, num_connected_label + 1):
        area = lss_filter.GetNumberOfPixels(i)  # 根据label获取连通域面积
        if area > area_max:
            area_max_label = i
            area_max = area

    np_output_mask = sitk.GetArrayFromImage(output_mask)

    res_mask = np.zeros_like(np_output_mask)
    res_mask[np_output_mask == area_max_label] = 1

    res_itk = sitk.GetImageFromArray(res_mask)
    res_itk.SetOrigin(itk_mask.GetOrigin())
    res_itk.SetSpacing(itk_mask.GetSpacing())
    res_itk.SetDirection(itk_mask.GetDirection())

    return res_itk

PS:本文方法会将像素值不同但连通的像素视为一个连通域。

如果在连通域分析的时候需要区分像素值,则要先将不同像素值label分散到多个SimpleITK.Image中。

如有误,烦请指正。

欢迎留言讨论。

参考:

SimpleITK三维图像分析

python实现3D连通域后处理

itk::simple::ConnectedComponentImageFilter Class Reference

itk::simple::LabelShapeStatisticsImageFilter Class Reference

  • 21
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值