python 如何在 SimpleITK 中从二进制图像中提取标签

How to extract labels from a Binary Image in SimpleITK in python

我想使用以下代码从二维二值图像中提取标签:

image2DThresh = sitk.Threshold(image2D, lower=stats.GetMinimum(), upper=127.500)
cca = sitk.ConnectedComponentImageFilter()
cca_image = cca.Execute(2D_Slice)
# Get the shape statistics of the labels using
labelStats = sitk.LabelShapeStatisticsImageFilter()

基本思想是在主图像中找到标签的平均强度、ROI 面积和 min/max 索引。我想要做的是使用阈值滤波器对图像进行二值化,然后在其上进行 运行 CCA 以获取所有标签。然后我用 LabelShapeStatisticsImageFilter() 获取每个标签的物理属性(当然除了标签0)并检查标签是否符合条件。问题是我无法在标签所在的主图像中获得平均强度。这就是为什么我建议使用 LabelIntensityStatisticsFilter,但是对于 python 2.7,SimpleITK 0.10 不可用。

您可能感兴趣的两个过滤器是 "LabelStatisticsImageFilter" 和 "LabelIntensityStatisticsImageFilter"。这些都在 SimpleITK 0.10 中可用,如果不是你有分布问题。两个过滤器都计算均值,但后者计算边界框和许多更高级的统计数据。

用法是这样的:

In [1]: import SimpleITK as sitk

In [2]: print sitk.Version()
SimpleITK Version: 0.10.0 (ITK 4.10)
Compiled: Aug 16 2016 17:21:32


In [3]: img = sitk.ReadImage("cthead1.png")

In [4]: cc = sitk.ConnectedComponent(img>100)

In [5]: stats = sitk.LabelIntensityStatisticsImageFilter()

In [6]: stats.Execute(cc,img)
Out[6]: <SimpleITK.SimpleITK.Image; proxy of <Swig Object of type 'std::vector< itk::simple::Image >::value_type *' at 0x2a6b540> >

In [7]: for l in stats.GetLabels():
   ...:     print("Label: {0} -> Mean: {1} Size: {2}".format(l, stats.GetMean(l), stats.GetPhysicalSize(l)))
   ...:     
Label: 1 -> Mean: 157.494210868 Size: 3643.8348071
Label: 2 -> Mean: 151.347826087 Size: 2.86239969136
Label: 3 -> Mean: 123.75 Size: 0.497808641975
Label: 4 -> Mean: 106.0 Size: 0.248904320988
Label: 5 -> Mean: 104.0 Size: 0.124452160494
Label: 6 -> Mean: 106.0 Size: 0.124452160494
Label: 7 -> Mean: 103.0 Size: 0.124452160494
Label: 8 -> Mean: 121.5 Size: 1.49342592593
Label: 9 -> Mean: 106.0 Size: 0.124452160494

您可以创建标签列表以保留或重新标记为 0(擦除),而不是打印。然后可以使用 ChangeLabelImageFilter 将此更改应用于标签图像。

阈值化、统计和标签部分的组合是一种功率分割方法,可以为许多任务使用和定制。它还可以作为更多复杂方法的起点。

所以我用numpy解决了这个问题。我正在发布代码,可能对以后的其他人有帮助!

def get_label(ccaimage, label, image2D):
# labelImage is the mask for a particular label
labelImage = sitk.Threshold(ccaimage, lower=label, upper=label)
#sitk_show(labelImage)
# get image as array
labelImageArray = sitk.GetArrayFromImage(labelImage)
image2Darray = sitk.GetArrayFromImage(image2D)
# ROI_1 is the minimum in the original image where the mask is equal to label
ROI_1 = image2Darray == np.min(image2Darray[labelImageArray == label])
plt.imshow(ROI_1)
plt.show()
# ROI_2 is the mask image
ROI_2 = labelImageArray == label
plt.imshow(ROI_2)
plt.show()
# AND gives me only those pixels which satisfy both conditions.
ROI = np.logical_and(image2Darray == np.min(image2Darray[labelImageArray == label]), labelImageArray == label )
avg = np.mean(image2Darray[labelImageArray == label])
print np.min(image2Darray[labelImageArray == label])
print np.where(ROI)
plt.imshow(ROI)
plt.show()