代码之家  ›  专栏  ›  技术社区  ›  RMS

计算对称曲面距离[Python]

  •  2
  • RMS  · 技术社区  · 7 年前

    我想计算两个二进制对象之间的表面距离度量,也称为肝肿瘤分割。我希望计算:

    • 平均对称表面距离
    • 均方根对称距离
    • Hausdorff距离(也称为最大对称距离)

    我发现有两个库可以帮助我计算这些指标,但我得到的结果相互矛盾,所以我对它们的工作原理感到困惑。

    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()])
    
    1. 乍一看,我不认为SimpleTk计算 对称的

    2. MedPy是一个可靠的图书馆吗?我可以计算对称根平均值吗 同意吗?

    3. 韵律学?
    4. 我应该计算毛勒距离图的绝对值吗?我不确定这会如何影响结果。 reference_distance_map = sitk.Abs(sitk.SignedMaurerDistanceMap(reference_segmentation, squaredDistance=False, useImageSpacing=True))
    2 回复  |  直到 7 年前
        1
  •  4
  •   zivy    7 年前

    @罗克珊

    我在这里假设您对在中计算的表面距离度量感到困惑 this SimpleITK notebook ?

    答案的其余部分引用了该代码。

    平均值/标准值/中值/最大值不对称(Hausdorff为)。

    使用SimpleTk,可以通过以下公式计算对称平均值和标准差: 计算分割的平均值和标准差,然后计算参考值(代码用于分割,所以只需切换角色,就可以获得参考值)。

    现在你得到了两个样本的平均值和标准差。要获得样本的大小,只需调用:

    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的默认行为)。

    如果您还有其他问题,请发到 ITK discourse forum .

        2
  •  2
  •   Dženan    7 年前

    符号距离映射是不对称的。Hausdorff距离应为。

    metro 在过去。

    对于Maurer来说,正距离意味着外部,负距离意味着内部。如果要计算分歧,则应取绝对值。

    推荐文章