医学图像处理(四):图像预处理的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)
获取最大连通区域:
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(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])