文章目录

  • 一、简介
  • 二、计算各类度量
    • ①Average surface distance 平均表面距离
    • ②Hausdorff distance 豪斯多夫距离
    • ③Surface overlap 表面重叠度
    • ④Surface dice 表面dice值
    • ⑤Volumetric dice 三维dice值
  • 三、公开竞赛中的度量
  • 四、最后

一、简介

当我们评价图像分割的质量和模型表现时,经常会用到各类表面距离的计算。这里推荐一个deepmind的表面距离度量计算库surface-distance。
该库的下载地址:https://download.csdn.net/download/Joker00007/12718748
Github地址:https://github.com/deepmind/surface-distance
(注:Github上的代码存在Bug,可直接在第一个链接下载,该文件是已经改完错误的)

这个库主要包含了以下几个表面距离计算:

  • Average surface distance 平均表面距离
  • Hausdorff distance 豪斯多夫距离
  • Surface overlap 表面重叠度
  • Surface dice 表面dice值
  • Volumetric dice 三维dice值

二、计算各类度量

该计算库的调用API都是类似的,首先调用compute_surface_distances这个函数计算出中间结果,再用这个中间结果去计算各类距离。
compute_surface_distances的参数有三个,mask_gt和mask_pred分别为ground truth和prediction的volume,spacing_mm是每个轴的体素间距。
体素间距是医疗影像上常见的一个参数,它的含义是,图像中相邻的两个体素(即两个点)间的直线距离转换为现实中的距离是多少毫米。例如,一个shape为(256, 256, 64)的array,spacing_mm为(1.1, 1.1, 3),实际表示的是 (281.6mm, 281.6mm, 192mm) 大小的块。体素间距不同,计算得到的surface distance也不同。如果不确定自己的数据体素间距是多少,就设为(1.0, 1.0, 1.0)。

  • 3D Volume的表面定义:对于一个体素,如果在其18邻域范围(请看上图,在3x3的方阵中,橘黄色方块表示当前体素,除了红色方块外,其他的都属于邻域范围)内至少有一个像素不是物体,则认为该体素属于表面,依次遍历所有的体素便得到volume的表面。
  • 表面距离:设P为prediction的表面点集,G为ground truth的Volume表面点集,P中任意一点的表面距离为该体素到G中所有体素的欧式距离的最小值,依次遍历P中所有的点即可得到表面距离。
①Average surface distance 平均表面距离

顾名思义,这个指标就是P中所有点的表面距离的平均。这个指标又可称为Average Symmetric Surface Distance (ASSD),它也是医疗图像分割竞赛CHAOS中的一个评估指标。平均表面距离的计算代码如下:

import surface_distance as surfdistsurface_distances = surfdist.compute_surface_distances(mask_gt, mask_pred, spacing_mm=(1.0, 1.0, 1.0))
avg_surf_dist = surfdist.compute_average_surface_distance(surface_distances)
②Hausdorff distance 豪斯多夫距离

关于这个距离的计算,很多人都讲的不是非常清晰,甚至有很多人介绍的是错的。这里我介绍一个比较简单清晰的计算流程,请对照下图阅读。

1.给定两个点集合A{ a0, a1, … }和B{ b0, b1, b2, …}
2.取A集合中的一点a0,计算a0到B集合中所有点的距离,保留最短的距离d0
3.遍历A集合中所有点,图中一共两点a0和a1,计算出d0和d1
4.比较所有的距离{ d0, d1 },选出最长的距离d1
5.这个最长的距离就是h,它是A→B单向豪斯多夫距离,记为h( A, B )
6.对于A集合中任意一点a,我们可以确定,以点a为圆心,h为半径的圆内部必有B集合中的点
7.交换A集合和B集合的角色,计算B→A的单向豪斯多夫距离h( B, A ),选出h( A, B )和h( B, A )中最长的距离,就是A,B集合的双向豪斯多夫距离

豪斯多夫距离95%的计算代码如下:

import surface_distance as surfdistsurface_distances = surfdist.compute_surface_distances(mask_gt, mask_pred, spacing_mm=(1.0, 1.0, 1.0))
hd_dist_95 = surfdist.compute_robust_hausdorff(surface_distances, 95)

compute_robust_hausdorff这个函数的第二个参数表示最大距离分位数,取值范围为0-100,它表示的是计算步骤4中,选取的距离能覆盖距离的百分比,例如我这里选取了95%,那么在计算步骤4中选取的不是最大距离,而是将距离从大到小排列后,取排名为5%的距离。这么做的目的是为了排除一些离群点所造成的不合理的距离,保持整体数值的稳定性。

③Surface overlap 表面重叠度

给定一个容许的误差距离,在此容差范围内的表面视作重叠部分,计算mask_gt和mask_pred的表面重叠比例。表面重叠度的计算代码如下:

import surface_distance as surfdistsurface_distances = surfdist.compute_surface_distances(mask_gt, mask_pred, spacing_mm=(1.0, 1.0, 1.0))
surface_overlap = surfdist.compute_surface_overlap_at_tolerance(surface_distances, 1)

compute_surface_overlap_at_tolerance函数的第二个参数表示容许误差,以mm为单位,例如我这里选择了1,那么容许误差也就是空间欧氏距离小于1mm的点都会被当做是重叠部分。
注意,这里返回的surface_overlap有两个值,分别代表pred->gt和gt->pred的重叠比例。大多数情况下这两个比例是相等的,但是在某些情况下是不同的

④Surface dice 表面dice值

给定一个容许的误差距离,在此容差范围内的表面视作重叠部分,计算mask_gt和mask_pred的表面重叠dice值。表面dice值的计算代码如下:

import surface_distance as surfdistsurface_distances = surfdist.compute_surface_distances(mask_gt, mask_pred, spacing_mm=(1.0, 1.0, 1.0))
surface_dice = surfdist.compute_surface_dice_at_tolerance(surface_distances, 1)

compute_surface_dice_at_tolerance这个函数的第二个参数跟表面重叠度函数的第二个参数是一样的用法。该函数的返回值只有一个,因为pred->gt和gt->pred的表面dice是相同的。

⑤Volumetric dice 三维dice值

计算pred与gt之间的三维dice值。注意,这与上面计算的表面dice不同,三维dice值会考虑空间中的每一个点而不仅仅是表面。三维dice的计算代码如下:

import surface_distance as surfdistvolume_dice = surfdist.compute_dice_coefficient(mask_gt, mask_pred)

该函数的返回值为0~1之间的float值,如果gt和pred均为空,那么会返回NAN值。

三、公开竞赛中的度量

这边统计一些公开竞赛中所选取的metric,不在surfdist库里的metric将加以括号。

  • CHAOS: Volumetric dice, Average surface distance, ( Relative absolute volume difference ), ( Maximum symmetric surface distance )
  • StructSeg: Volumetric dice, Hausdorff distance 95%
  • RT-MAC: Volumetric dice, Average surface distance, Hausdorff distance 95%
  • KiTS19: Volumetric dice
  • SegTHOR: Volumetric dice, Hausdorff distance 95%

这边可以看出,Volumetric dice和Hausdorff distance 95%是最常用的两种metric,推荐大家在评估自己的模型的时候优先使用这两种。

四、最后

自己写的Average surface distance和95%Hausdorff distance函数调用

import surface_distance as surfdist
import nibabel as nib
import numpy as np
import h5pymask_pred_path = r"E:\...\pred_segmentation_case000051.nii.gz"
mask_gt_path = r"E:\...\segmentation_case000051.nii.gz"
mask_gt = nib.load(mask_gt_path)
mask_pred = nib.load(mask_pred_path)
spacing_mm = h5py.File(r'E:\...\pixel_size.mat', 'r')['pixel_size'][:]#Average surface distance 平均表面距离
def mBoudDis(mask_pred, mask_gt, spacing_mm_s):width_t, height_t, queue0_t, queue1_t = mask_gt.dataobj.shapewidth_p, height_p, queue0_p, queue1_p = mask_pred.dataobj.shape mB = []if(queue1_t != queue1_p):return("Error,The two sets of data have different dimensions")else:for i in range(queue1_t):gt = mask_gt.dataobj[:,:,:,i]pred = mask_pred.dataobj[:,:,:,i]gt = gt.astype(np.bool)pred = pred.astype(np.bool)surface_distances = surfdist.compute_surface_distances(gt, pred, spacing_mm = spacing_mm_s)#avg_surf_dist有两个参数,第一个参数是average_distance_gt_to_pred,第二个参数是average_distance_pred_to_gtsurf_dist = surfdist.compute_average_surface_distance(surface_distances)avg_surf_dist = (surf_dist[0]+surf_dist[1])/2mB.append(avg_surf_dist)   return  mB
print("ASD:",mBoudDis(mask_pred, mask_gt, spacing_mm))#95%Hausdorff distance 豪斯多夫距离
def hausd95(mask_pred, mask_gt, spacing_mm_s):width_t, height_t, queue0_t, queue1_t = mask_gt.dataobj.shapewidth_p, height_p, queue0_p, queue1_p = mask_pred.dataobj.shape mH = []if(queue1_t != queue1_p):return("Error,The two sets of data have different dimensions")else:for i in range(queue1_t):gt = mask_gt.dataobj[:,:,:,i]pred = mask_pred.dataobj[:,:,:,i]gt = gt.astype(np.bool)pred = pred.astype(np.bool)surface_distances = surfdist.compute_surface_distances(gt, pred, spacing_mm = spacing_mm_s)hd_dist_95 = surfdist.compute_robust_hausdorff(surface_distances, 95) mH.append(hd_dist_95)   return mH
print("mH95:",hausd95(mask_pred, mask_gt, spacing_mm))

图像分割评估指标——surface-distance计算库相关推荐

  1. ML之分类预测:分类预测评估指标之AUC计算的的两种函数具体代码案例实现

    ML之分类预测:分类预测评估指标之AUC计算的的两种函数具体代码案例实现 目录 分类预测评估指标之AUC计算的的两种函数代码案例实现 输出结果 实现代码

  2. 图像分割评估指标之Hausdorff distance 豪斯多夫距离

    我又来更新啦,今天带来的内容是Hausdorff distance 豪斯多夫距离的原理介绍及MindSpore的实现代码. 欢迎关注知乎: 世界是我改变的 知乎上的原文链接 当我们评价图像分割的质量和 ...

  3. 模型评估与改进(三)// 评估指标

    1.常用的评估指标有哪些? 回答:评估分类算法的性能用精度accuracy:评估回归算法的性能用R方(R的平方). 第一部分:二分类的评估指标 2.精度accuracy指标对评估二分类模型的不足? 回 ...

  4. 1.3 单一数字评估指标-深度学习第三课《结构化机器学习项目》-Stanford吴恩达教授

    ←上一篇 ↓↑ 下一篇→ 1.2 正交化 回到目录 1.4 满足和优化指标 单一数字评估指标 (Single Number Evaluation Metric) 无论你是调整超参数,或者是尝试不同的学 ...

  5. Lesson 5.分类模型决策边界与模型评估指标

    Lesson 5.分类模型决策边界与模型评估指标(上) 在逻辑回归的算法基础内容结束之后,我们还需要补充一些关于分类模型的基础知识,包括观察分类模型判别性能的决策边界基本的概念与实现方法,同时也包括对 ...

  6. 绝对不容错过:最完整的检测模型评估指标mAP计算指南(附代码)在这里!

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 前言 本文翻译自Measuring Object Detectio ...

  7. Python使用numpy包编写自定义函数计算均方误差(MSE、mean squared error)、评估回归模型和时间序列模型、解读MSE评估指标

    Python使用numpy包编写自定义函数计算均方误差(MSE.mean squared error).评估回归模型和时间序列模型.解读MSE评估指标 目录

  8. R语言计算F1评估指标实战:F1 score、使用R中caret包中的confusionMatrix()函数为给定的logistic回归模型计算F1得分(和其他指标)

    R语言计算F1评估指标实战:F1 score.使用R中caret包中的confusionMatrix()函数为给定的logistic回归模型计算F1得分(和其他指标) 目录

  9. 模型评估指标micro avg、macro avg和weighted avg的计算方式及区别

    模型评估指标micro avg.macro avg和weighted avg的计算方式及区别-技术圈

最新文章

  1. hive 添加UDF(user define function) hive的insert语句
  2. SQLServer权限
  3. ezdpl Linux自动化部署实战
  4. IBM、甲骨文、CNCF 就谷歌对 Istio 治理的处理提出抗议
  5. ajax实现两个aspx跳转,请问ajax执行成功后可以跳转到另一个页面吗?
  6. Bear in the Field(CF-385E)
  7. Python学习笔记之头部文件
  8. 优云数智UMCloud CTO王璞:IaaS+PaaS驱动私有云未来十年
  9. winform 调用外部程序和多线程
  10. (四)比特币时间序列数据的AI预测
  11. 卡内基梅隆计算机专业,详解卡内基梅隆大学计算机学院
  12. ssh 切换用户_从零开始学习华为路由交换 | 配置ssh远程管理
  13. Windows 8 相关资源 MSDN原版
  14. 招聘PHP聚合系统,Thinkphp5开发OA办公系统之招聘申请
  15. 小程序 蓝牙连接(出现的问题和一些解决方法)
  16. android虚拟按键趋势,为什么Android虚拟按键老被吐槽但却有厂商坚持在做?
  17. Android MVC、MVP和MVVP的概念、运用及区别
  18. CCF公布国家集训队50进15名单!5月确定IOI2019选手!
  19. 推荐系统之用户多兴趣建模(一)
  20. MSF图形化界面Viper(炫彩蛇)下载与使用

热门文章

  1. linux index shell,Linux shell 数组使用
  2. 安卓通过Linuxdeploy安装Linux ——三星P600平板电脑
  3. 切比雪夫不等式,大数定理,中心极限定理
  4. Vue input输入框中的值如何变成黑点
  5. oracle 行转列sql语句,行转列(sql行转列)
  6. 作业1-采用Prim算法和Kruskal算法构造最小生成树
  7. 数据分析成果落地难?你需要注意这五个问题
  8. c语言编写1000以内素数的函数6,C语言求1000以内的素数
  9. HDD大容量硬盘为什么未衰反兴了?
  10. 【面试题】973- 一篇由简到难的 Vue 面试题+详解答案