医学图像分割常用指标及代码(pytorch)

现在,医学图像分割有很多现成的工具包可以快速测量一些指标,比如python中的medpy库。但是,我们还是要学习一下滴!该文章列出了一些常用的指标,并解释了它的原理。

一、医学图像分割常用指标及代码

1. Classic measures

1、What is T 1 、 T 0 、 P 1 、 P 0 T_1、T_0、P_1、P_0 T1T0P1P0? 1

在这里插入图片描述
T 1 T_1 T1蓝色部分表示真实脑肿瘤区域(GroundTruth)
T 0 T_0 T0蓝色的其它部分为正常脑区域
P 1 P_1 P1红色部分表示预测的脑肿瘤区域
P 0 P_0 P0 红色的其它部分为预测的正常脑区域

2、What is TP、TN、FP、TN?

在这里插入图片描述
(a) TP:True Positive,被判定为正样本,事实上也是正样本 ,即蓝色与红色的交集
(b) TN:True Negative,被判定为负样本,事实上也是负样本,即红色与蓝色以外区域
(b) FP:False Positive,被判定为正样本,但事实上是负样本,即红色中除了蓝色部分
(d) FN:False Negative,被判定为负样本,但事实上是正样本,即蓝色中除了红色部分

3、Sensitivity (Recall, true positive rate)

真阳性率(true positive rate,TPR)也称为敏感度和召回率,它衡量的是真实背景中的阳性体素部分,即衡量的是分割实验中能分割感兴趣区域的能力。
R e c a l l = S e n s i t i v i t y = T P R = R g t ⋂ R p r e d R g t = T P T P + F N Recall = Sensitivity = TPR = \frac{R_{gt} \bigcap R_{pred}}{R_{gt}}= \frac{TP}{TP + FN} Recall=Sensitivity=TPR=RgtRgtRpred=TP+FNTP
R g t R_{gt} Rgt 是ground true 的分割结果, R p r e d R_{pred} Rpred是预测的分割结果。

pytorch代码:

def recall(predict, target): #Sensitivity, Recall, true positive rate都一样
    if torch.is_tensor(predict):
        predict = torch.sigmoid(predict).data.cpu().numpy()
    if torch.is_tensor(target):
        target = target.data.cpu().numpy()

    predict = numpy.atleast_1d(predict.astype(numpy.bool))
    target = numpy.atleast_1d(target.astype(numpy.bool))

    tp = numpy.count_nonzero(predict & target)
    fn = numpy.count_nonzero(~predict & target)

    try:
        recall = tp / float(tp + fn)
    except ZeroDivisionError:
        recall = 0.0

    return recall

4、Specificity(true negative rate)

真阴性率(true negative rate,TNR)也称为特异性,它衡量的是地面真值分割中的负体素(background)部分,即其衡量的是分割实验中能正确判断不是感兴趣区域像素点的能力。
S p e c i f i c i t y = T N R = T N T N + F P Specificity = TNR = \frac{TN}{TN + FP} Specificity=TNR=TN+FPTN

pytorch代码:

def specificity(predict, target): #Specificity,true negative rate一样
    if torch.is_tensor(predict):
        predict = torch.sigmoid(predict).data.cpu().numpy()
    if torch.is_tensor(target):
        target = target.data.cpu().numpy()

    predict = numpy.atleast_1d(predict.astype(numpy.bool))
    target = numpy.atleast_1d(target.astype(numpy.bool))

    tn = numpy.count_nonzero(~predict & ~target)
    fp = numpy.count_nonzero(predict & ~target)

    try:
        specificity = tn / float(tn + fp)
    except ZeroDivisionError:
        specificity = 0.0

    return specificity

5、Precision

精确度,也叫阳性预测值(PPV)。
P r e c i s i o n = P P V = R g t ⋂ R p r e d R p r e d = T P T P + F P Precision = PPV = \frac{R_{gt} \bigcap R_{pred}}{R_{pred}}= \frac{TP}{TP + FP} Precision=PPV=RpredRgtRpred=TP+FPTP
pytorch代码:

def precision(predict, target):
    if torch.is_tensor(predict):
        predict = torch.sigmoid(predict).data.cpu().numpy()
    if torch.is_tensor(target):
        target = target.data.cpu().numpy()

    predict = numpy.atleast_1d(predict.astype(numpy.bool))
    target = numpy.atleast_1d(target.astype(numpy.bool))

    tp = numpy.count_nonzero(predict & target)
    fp = numpy.count_nonzero(predict & ~target)

    try:
        precision = tp / float(tp + fp)
    except ZeroDivisionError:
        precision = 0.0

    return precision

2. Similarity

1、Dice Coefficient

DICE(值域为[0,1]):也称为重叠指数,表示两个物体相交的面积占总面积的比值。
D I C E = 2 ∣ P 1 ⋂ T 1 ∣ ∣ P 1 ∣ + ∣ T 2 ∣ = 2 ∣ R p r e d ⋂ R g t ∣ ∣ R p r e d ∣ + ∣ R g t ∣ = 2 T P 2 T P + F P + F N DICE = \frac{2 \vert P_1 \bigcap T_1 \vert}{\vert P_1 \vert + \vert T_2 \vert}= \frac{2 \vert R_{pred}\bigcap R_{gt} \vert}{\vert R_{pred} \vert + \vert R_{gt} \vert} = \frac{2TP}{2TP + FP + FN} DICE=P1+T22P1T1=Rpred+Rgt2RpredRgt=2TP+FP+FN2TP
pytorch 代码:

import torch
import numpy
from medpy import metric

predict = numpy.array([1, 2, 3, 4], dtype=float) #predict是预测结果
target = numpy.array([1, 0, 1, 2], dtype=float) #target是ground true

def dice(predict, target):
    if torch.is_tensor(predict):
        predict = torch.sigmoid(predict).data.cpu().numpy()
    if torch.is_tensor(target):
        target = target.data.cpu().numpy()

    predict = numpy.atleast_1d(predict.astype(numpy.bool))  #转一维数组
    target = numpy.atleast_1d(target.astype(numpy.bool))

    intersection = numpy.count_nonzero(predict & target) #计算非零个数

    size_i1 = numpy.count_nonzero(predict)
    size_i2 = numpy.count_nonzero(target)

    try:
        dice = 2. * intersection / float(size_i1 + size_i2)
    except ZeroDivisionError:
        dice = 0.0

    return dice
 
dice1 = dice(predict, target)
dice2 = metric.binary.dc(predict, target)
print(dice1, dice2)

结果如下:
在这里插入图片描述

2、Jaccard Coefficient

J A C = ∣ R g t ⋂ R p r e d ∣ ∣ R g t ⋃ R p r e d ∣ = T P T P + F P + F N JAC = \frac{\vert R_{gt} \bigcap R_{pred} \vert}{\vert R_{gt} \bigcup R_{pred} \vert} = \frac{TP}{TP + FP + FN} JAC=RgtRpredRgtRpred=TP+FP+FNTP
因此,DICE和JAC之间的关系是:
D I C E = 2 J A C 1 + J A C DICE = \frac {2JAC}{1 + JAC} DICE=1+JAC2JAC

pytorch代码:

from medpy import metric
import torch
import numpy

predict = numpy.array([[1, 2, 3, 4], [5, 6, 7, 8]], dtype=float)
target = numpy.array([[1, 6, 1, 0], [1, 2, 0, 0]], dtype=float)

def jac(predict, target):
    if torch.is_tensor(predict):
        predict = torch.sigmoid(predict).data.cpu().numpy()
    if torch.is_tensor(target):
        target = target.data.cpu().numpy()

    predict = numpy.atleast_1d(predict.astype(numpy.bool))
    target = numpy.atleast_1d(target.astype(numpy.bool))

    intersection = numpy.count_nonzero(predict & target)
    union = numpy.count_nonzero(predict | target)

    jac = float(intersection) / float(union)

    return jac

jac1 = jac(predict, target)
jac2 = metric.binary.jc(predict, target)
print(jac1, jac2)

#验证一下DICE和JAC的关系
dice1 = dice(predict, target)
dice2 = 2 * jac1 / (1 + jac1)
print(dice1, dice2)

结果如下:
在这里插入图片描述

3. Distance

这部分的代码过于复杂,就不一一实现了。哭唧唧,太难了~

1、Hausdorff Distance (HD)

Hausdorff_95就是是最后的值乘以95%,目的是为了消除离群值的一个非常小的子集的影响。
在这里插入图片描述

2、Average Surface Distance (ASD)

二、快速实现指标的工具和代码

医学图像处理的python库medpy:
官方文档链接
在这里插入图片描述
以上各个指标的pytorch代码都是参考medpy包中的代码,那我们如何快速实现这些指标呢?
答案如下(直接调包好爽啊哈哈哈哈):

from medpy import metric

def calculate_metric_percase(pred, gt):
    dice = metric.binary.dc(pred, gt)
    jc = metric.binary.jc(pred, gt)
    hd = metric.binary.hd95(pred, gt)
    asd = metric.binary.asd(pred, gt)
    return dice, jc, hd, asd

参考资料


  1. 分割常用评价指标Dice、Hausdorff_95、IOU、PPV等
    2.机器学习&图像分割——模型评价总结
    3.CSDN中的LaTeX数学公式的基本操作
    4.Metrics for evaluating 3D medical image segmentation: analysis, selection, and tool. ↩︎

  • 54
    点赞
  • 345
    收藏
    觉得还不错? 一键收藏
  • 22
    评论
对于医学图像分割的任务,PyTorch是一个非常流行和强大的深度学习框架之一。你可以使用PyTorch来构建和训练神经网络模型,用于医学图像分割任务。 下面是一些使用PyTorch进行医学图像分割的一般步骤: 1. 数据准备:首先,你需要准备医学图像数据集。这包括收集和标记一组医学图像,通常是由专业人员手动进行标注。你需要将这些图像划分为训练集和测试集。 2. 构建模型:使用PyTorch构建分割模型。常见的模型包括U-Net、FCN(全卷积网络)、DeepLab等。这些模型通常由编码器和解码器组成,可以有效地处理医学图像分割任务。 3. 数据预处理:在将图像提供给模型之前,需要对其进行预处理。这可能包括缩放、裁剪、标准化等操作,以确保输入数据的一致性和合理性。 4. 模型训练:使用准备好的训练集对模型进行训练。这涉及到定义损失函数(如交叉熵损失、Dice系数等)和优化器(如Adam、SGD等),并在训练过程中迭代地调整模型的权重。 5. 模型评估:在训练完成后,使用准备好的测试集对模型进行评估。这包括计算分割结果与标注结果之间的相似度指标,如Dice系数、IoU(交并比)等。 6. 模型应用:一旦模型训练和评估完成,你可以将其应用于新的医学图像,以进行分割任务。这可能涉及到对新图像进行预处理和后处理的步骤。 总的来说,PyTorch提供了丰富的工具和库,可以用于医学图像分割任务的开发和实施。它具有灵活性和可扩展性,可以帮助你构建高性能的分割模型。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值