医学图像处理(四):图像预处理的tricks

1. 空洞填充


参考python-opencv去除小面积区域/孔洞填充(二值图像)

2.根据连通区域去除假阳性


参考深度学习,分割后处理之通过连通成分分析去除假阳性区域,提高分割准确度

连通区域划分:

def get(sitk_maskimg):
    cc_filter = sitk.ConnectedComponentImageFilter()
    cc_filter.SetFullyConnected(True)
    output_mask = cc_filter.Execute(sitk_maskimg)
    output_mask = sitk.GetArrayFromImage(output_mask)
    print(output_mask)

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

获取最大连通区域:

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

3.scipy-ndimage:膨胀、腐蚀、距离变换

scipy-ndimage用法
图像去噪:先腐蚀后膨胀,参考python图像处理(八)——形态学运算之图像腐蚀与图像膨胀

4.瘤周区域扩展(基于膨胀操作)

mask用最近邻插值sitk.sitkNearestNeighbor,CT图像用线性插值(why?)
Resample之后的ROI只能和resample之后的原图一起提取组学特征,spacing不匹配的话就会报错,所以原图也要Resample
参考影像组学nii瘤周扩展Python代码思路

5.判断两区域是否相交

numpy.logical_and()
python - 检查两个轮廓是否相交?

6.numpy ndarray判断矩阵是否含有一个元素(ndarray.contains())

array.__contains__(0)

7.边缘填充

参考numpy.pad()函数使用详解

numpy.pad(array, pad_width, mode=‘constant’, **kwargs)
多维数组填充,参考python中numpy.pad()函数的使用
np.pad(arr3D, ((0, 0), (1, 1), (2, 2)), 'constant')

参数解析

pad_width

表示每个轴(axis)边缘需要填充的数值数目。
参数输入方式为:((before_1, after_1), … (before_N, after_N)),其中(before_1, after_1)表示第1轴两边缘分别填充before_1个和after_1个数值。

mode

表示填充的方式(取值:str字符串或用户提供的函数),总共有12种填充模式。
默认为’constant’方式填充。

**kwargs

表示关键字参数,它本质上是一个dict。
1、constant_values : sequence or scalar, optional。用于‘constant’填充方式指定的填充值。
2、stat_length : sequence or int, optional。用于 ‘maximum’, ‘mean’, ‘median’,和‘minimum’填充方式中。每个轴边缘用于计算统计量的数据个数,默认用到整个轴。
3、end_values : sequence or scalar, optional。用于 ‘linear_ramp’填充方式,设定结束值。
4、reflect_type : {‘even’, ‘odd’}, optional,默认为‘even’。

填充方式

1、‘constant’

表示连续填充相同的值,每个轴可以分别指定填充值,constant_values=(x, y)时前面用x填充,后面用y填充,缺省值填充0。

>>> a = [1, 2, 3, 4, 5]
>>> np.pad(a, (2, 3), 'constant', constant_values=(4, 6))
array([4, 4, 1, ..., 6, 6, 6])
2、‘edge’

用数组的边缘值填充。

np.pad(a, (2, 3), 'edge')
array([1, 1, 1, ..., 5, 5, 5])
3、‘linear_ramp’

表示用边缘递减的方式填充。

>>> np.pad(a, (2, 3), 'linear_ramp', end_values=(5, -4))
array([ 5,  3,  1,  2,  3,  4,  5,  2, -1, -4])
4、‘maximum’

表示最大值填充。

>>> np.pad(a, (2,), 'maximum')
array([5, 5, 1, 2, 3, 4, 5, 5, 5])
5、‘mean’

表示均值填充。

>>> np.pad(a, (2,), 'mean')
array([3, 3, 1, 2, 3, 4, 5, 3, 3])
6、‘median’

表示中位数填充。

>>> np.pad(a, (2,), 'median')
array([3, 3, 1, 2, 3, 4, 5, 3, 3])

设置统计长度。

>>> np.pad(a, (2,), 'median',stat_length=(2,3))
array([2, 2, 1, 2, 3, 4, 5, 4, 4])
其他参见引用文章
posted @ 2022-10-08 14:41  梅雨明夏  阅读(1178)  评论(0编辑  收藏  举报