计算对称表面距离 [Python]
Compute symmetric surface distances [Python]
我想计算 2 个二进制对象之间的表面距离度量,也就是肝肿瘤的分割。我要计算:
- 平均对称表面距离
- 均方根对称距离
- Hausdorff 距离(也称为最大对称距离)
我找到了两个可以帮助我计算这些指标的库,但我得到的结果相互矛盾,所以我对它们的工作方式感到困惑。
- 简单ITK:https://itk.org/SimpleITKDoxygen/html/classitk_1_1simple_1_1SignedMaurerDistanceMapImageFilter.html
https://itk.org/SimpleITKDoxygen/html/classitk_1_1simple_1_1HausdorffDistanceImageFilter.html
- 医学派:
https://github.com/loli/medpy/. DOCS
这是我的 Simple ITK 和 MedPy 代码。
from medpy import metric
import pandas as pd
import SimpleITK as sitk
import numpy as np
reference_segmentation = sitk.ReadImage('tumorSegm', sitk.sitkUInt8)
segmentation = sitk.ReadImage('tumorSegm2',sitk.sitkUInt8)
class SurfaceDistanceMeasuresITK(Enum):
hausdorff_distance, max_surface_distance, avg_surface_distance, median_surface_distance, std_surface_distance = range(5)
class MedpyMetricDists(Enum):
hausdorff_distance, avg_surface_distance, avg_symmetric_surface_distance = range(3)
surface_distance_results = np.zeros((1,len(SurfaceDistanceMeasuresITK.__members__.items())))
surface_dists_Medpy = np.zeros((1,len(MedpyMetricDists.__members__.items())))
segmented_surface = sitk.LabelContour(segmentation)
# init signed mauerer distance as reference metrics
reference_distance_map = sitk.Abs(sitk.SignedMaurerDistanceMap(reference_segmentation, squaredDistance=False, useImageSpacing=True))
label_intensity_statistics_filter = sitk.LabelIntensityStatisticsImageFilter()
label_intensity_statistics_filter.Execute(segmented_surface, reference_distance_map)
hausdorff_distance_filter = sitk.HausdorffDistanceImageFilter()
hausdorff_distance_filter.Execute(reference_segmentation, segmentation)
surface_distance_results[0,SurfaceDistanceMeasuresITK.hausdorff_distance.value] = hausdorff_distance_filter.GetHausdorffDistance()
surface_distance_results[0,SurfaceDistanceMeasuresITK.max_surface_distance.value] = label_intensity_statistics_filter.GetMaximum(label)
surface_distance_results[0,SurfaceDistanceMeasuresITK.avg_surface_distance.value] = label_intensity_statistics_filter.GetMean(label)
surface_distance_results[0,SurfaceDistanceMeasuresITK.median_surface_distance.value] = label_intensity_statistics_filter.GetMedian(label)
surface_distance_results[0,SurfaceDistanceMeasuresITK.std_surface_distance.value] = label_intensity_statistics_filter.GetStandardDeviation(label)
surface_distance_results_df = pd.DataFrame(data=surface_distance_results, index = list(range(1)),
columns=[name for name, _ in SurfaceDistanceMeasuresITK.__members__.items()])
img_array = sitk.GetArrayFromImage(reference_segmentation)
seg_array = sitk.GetArrayFromImage(segmentation)
# reverse array in the order x, y, z
img_array_rev = np.flip(img_array,2)
seg_array_rev = np.flip(seg_array,2)
vxlspacing = segmentation.GetSpacing()
surface_dists_Medpy[0,MedpyMetricDists.hausdorff_distance.value] = metric.binary.hd(seg_array_rev,img_array_rev, voxelspacing=vxlspacing)
surface_dists_Medpy[0,MedpyMetricDists.avg_surface_distance.value] = metric.binary.asd(seg_array_rev,img_array_rev, voxelspacing=vxlspacing)
surface_dists_Medpy[0,MedpyMetricDists.avg_symmetric_surface_distance.value] = metric.binary.assd(seg_array_rev,img_array_rev, voxelspacing=vxlspacing)
surface_dists_Medpy_df = pd.DataFrame(data=surface_dists_Medpy, index = list(range(1)),
columns=[name for name, _ in MedpyMetricDists.__members__.items()])
乍一看,我不认为 SimpleITK 计算
对称 距离。该库中的那些有任何实现吗?如何获得它们?
MedPy 是可靠的库吗?我可以计算对称根均值吗
与之相符?
- 用于计算表面距离的库的其他推荐
指标?
- 我应该计算 Mauerer 距离图的绝对值吗?我不确定它如何影响结果。
reference_distance_map = sitk.Abs(sitk.SignedMaurerDistanceMap(reference_segmentation, squaredDistance=False, useImageSpacing=True))
带符号的距离图不对称。豪斯多夫距离应该是。
对于网格比较,我过去使用metro。
对于 Maurer,正距离表示外侧,负距离表示内侧。如果要计算不一致,应该取绝对值。
@Roxanne
我在这里假设您对 this SimpleITK notebook 中计算的表面距离测量感到困惑?
其余答案参考该代码。
mean/std/median/maximum 不是对称的(Hausdorff 是)。
使用 SimpleITK,您可以通过以下方式计算对称均值和标准差
计算分割的均值和标准差,然后作为参考(代码为分割做的,所以只需切换角色,你就可以得到它作为参考)。
现在你得到了两个样本的均值和标准差。要获得样本的大小,只需调用:
label_intensity_statistics_filter.GetNumberOfPixels(label)
根据 n1、m1、s1、n2、m2、s2 的知识计算对称均值和标准差:
m = (n1*m1 + n2*m2)/(n1+n2)
s = np.sqrt((n1*(s1**2+(m1-m)**2) + n2*(s2**2+(m2-m)**2))/(n1+n2))
请注意,标准差的样本估计是有偏差的版本(类似于 numpy.std 的默认行为)。
如果您还有其他问题,请 post 至 ITK discourse forum。
我想计算 2 个二进制对象之间的表面距离度量,也就是肝肿瘤的分割。我要计算:
- 平均对称表面距离
- 均方根对称距离
- Hausdorff 距离(也称为最大对称距离)
我找到了两个可以帮助我计算这些指标的库,但我得到的结果相互矛盾,所以我对它们的工作方式感到困惑。
- 简单ITK:https://itk.org/SimpleITKDoxygen/html/classitk_1_1simple_1_1SignedMaurerDistanceMapImageFilter.html https://itk.org/SimpleITKDoxygen/html/classitk_1_1simple_1_1HausdorffDistanceImageFilter.html
- 医学派: https://github.com/loli/medpy/. DOCS
这是我的 Simple ITK 和 MedPy 代码。
from medpy import metric
import pandas as pd
import SimpleITK as sitk
import numpy as np
reference_segmentation = sitk.ReadImage('tumorSegm', sitk.sitkUInt8)
segmentation = sitk.ReadImage('tumorSegm2',sitk.sitkUInt8)
class SurfaceDistanceMeasuresITK(Enum):
hausdorff_distance, max_surface_distance, avg_surface_distance, median_surface_distance, std_surface_distance = range(5)
class MedpyMetricDists(Enum):
hausdorff_distance, avg_surface_distance, avg_symmetric_surface_distance = range(3)
surface_distance_results = np.zeros((1,len(SurfaceDistanceMeasuresITK.__members__.items())))
surface_dists_Medpy = np.zeros((1,len(MedpyMetricDists.__members__.items())))
segmented_surface = sitk.LabelContour(segmentation)
# init signed mauerer distance as reference metrics
reference_distance_map = sitk.Abs(sitk.SignedMaurerDistanceMap(reference_segmentation, squaredDistance=False, useImageSpacing=True))
label_intensity_statistics_filter = sitk.LabelIntensityStatisticsImageFilter()
label_intensity_statistics_filter.Execute(segmented_surface, reference_distance_map)
hausdorff_distance_filter = sitk.HausdorffDistanceImageFilter()
hausdorff_distance_filter.Execute(reference_segmentation, segmentation)
surface_distance_results[0,SurfaceDistanceMeasuresITK.hausdorff_distance.value] = hausdorff_distance_filter.GetHausdorffDistance()
surface_distance_results[0,SurfaceDistanceMeasuresITK.max_surface_distance.value] = label_intensity_statistics_filter.GetMaximum(label)
surface_distance_results[0,SurfaceDistanceMeasuresITK.avg_surface_distance.value] = label_intensity_statistics_filter.GetMean(label)
surface_distance_results[0,SurfaceDistanceMeasuresITK.median_surface_distance.value] = label_intensity_statistics_filter.GetMedian(label)
surface_distance_results[0,SurfaceDistanceMeasuresITK.std_surface_distance.value] = label_intensity_statistics_filter.GetStandardDeviation(label)
surface_distance_results_df = pd.DataFrame(data=surface_distance_results, index = list(range(1)),
columns=[name for name, _ in SurfaceDistanceMeasuresITK.__members__.items()])
img_array = sitk.GetArrayFromImage(reference_segmentation)
seg_array = sitk.GetArrayFromImage(segmentation)
# reverse array in the order x, y, z
img_array_rev = np.flip(img_array,2)
seg_array_rev = np.flip(seg_array,2)
vxlspacing = segmentation.GetSpacing()
surface_dists_Medpy[0,MedpyMetricDists.hausdorff_distance.value] = metric.binary.hd(seg_array_rev,img_array_rev, voxelspacing=vxlspacing)
surface_dists_Medpy[0,MedpyMetricDists.avg_surface_distance.value] = metric.binary.asd(seg_array_rev,img_array_rev, voxelspacing=vxlspacing)
surface_dists_Medpy[0,MedpyMetricDists.avg_symmetric_surface_distance.value] = metric.binary.assd(seg_array_rev,img_array_rev, voxelspacing=vxlspacing)
surface_dists_Medpy_df = pd.DataFrame(data=surface_dists_Medpy, index = list(range(1)),
columns=[name for name, _ in MedpyMetricDists.__members__.items()])
乍一看,我不认为 SimpleITK 计算 对称 距离。该库中的那些有任何实现吗?如何获得它们?
MedPy 是可靠的库吗?我可以计算对称根均值吗 与之相符?
- 用于计算表面距离的库的其他推荐 指标?
- 我应该计算 Mauerer 距离图的绝对值吗?我不确定它如何影响结果。
reference_distance_map = sitk.Abs(sitk.SignedMaurerDistanceMap(reference_segmentation, squaredDistance=False, useImageSpacing=True))
带符号的距离图不对称。豪斯多夫距离应该是。
对于网格比较,我过去使用metro。
对于 Maurer,正距离表示外侧,负距离表示内侧。如果要计算不一致,应该取绝对值。
@Roxanne
我在这里假设您对 this SimpleITK notebook 中计算的表面距离测量感到困惑?
其余答案参考该代码。
mean/std/median/maximum 不是对称的(Hausdorff 是)。
使用 SimpleITK,您可以通过以下方式计算对称均值和标准差 计算分割的均值和标准差,然后作为参考(代码为分割做的,所以只需切换角色,你就可以得到它作为参考)。
现在你得到了两个样本的均值和标准差。要获得样本的大小,只需调用:
label_intensity_statistics_filter.GetNumberOfPixels(label)
根据 n1、m1、s1、n2、m2、s2 的知识计算对称均值和标准差:
m = (n1*m1 + n2*m2)/(n1+n2)
s = np.sqrt((n1*(s1**2+(m1-m)**2) + n2*(s2**2+(m2-m)**2))/(n1+n2))
请注意,标准差的样本估计是有偏差的版本(类似于 numpy.std 的默认行为)。
如果您还有其他问题,请 post 至 ITK discourse forum。