Hello everyone! 这篇文章将介绍Dice coefficient以及其实现
Introduction
Dice coefficient 是 Lee R. Dice 在1945年为评估生物种群提出的一种度量方法[1]。后来不同领域的学者都将其引入到自己的专业。这里,我将介绍Dice codfficient 在图像分割领域作为评价指标的理解与实现。
Segmentation
图像分割包含有语义分割、示例分割。在语义分割中,我们需要对给定的图片做如下处理:
- 标记出所有属于背景类别的点。
- 标记出属于我们关心类别的所有点。
通常的分割方法有:
- based on threshold
- region growing
- interactive segmenation
- gradient based
- classifier
- CNN (Unet)[3]
一个例子
现在我们要对下图分割出鱼和背景。
渔业专家给出的ground truth 是下图A
我们计算出的结果是下图B
我们可以看到B图与A图是有差距的,在鱼尾部的效果不好,没有分割出凸起部位。那么我们该如何评价这两者差距呢?
最初步的想法是计算准确率:
Accuracy=(TP+FN)/(TP+FN+FP+FN)
或者召回率
Recall (=Sensitivity)=TP/(TP+FN)
或者精度
Precision=TP/(TP+FP)
以及F-score (sometimes called F-factoror F1 measure)
=2* precision* recall/(precision+recall)
此时,引入一个和以上评价指标类似的 Dice coefficent
s=\frac{2|X \cap Y|}{|X|+|Y|}
我们可以借助两个圆A和B理解上面的公式。对于两个图像,如果没有重叠的部分,则Dice coefficient = 0. 也就是说,如果分割的目标真实区域和预测区域没有任何交集,则意味着在这个区域上的分割失败。但是,如果有重叠部分 A \cap B, 则说明这部分重叠区域是分割正确的。我们将这部分区域面积的2倍与两个圆和的比值设为Dice coefficient. 此时:0<DSC<1. 如果两个圆完全重合,则Dice coefficient = 1, 这意味着分割很成功。
This figure is copyright by ] Zou, Kelly H. et al.[2]
这里我们给出计算两个图像Dice Coefficient 的 Python代码
def dice_coef(y_true, y_pred):
smooth = 1
y_true_f = y_true.flatten()
y_pred_f = y_pred.flatten()
intersection = np.sum(y_true_f * y_pred_f)
return (2. * intersection + smooth) / (np.sum(y_true_f) + np.sum(y_pred_f) + smooth)
如果我们对几百张图片进行了分割,我们可以对每个图像计算Dice coefficient后,求平均。这里也给出计算一组图像的平均Dice coefficient代码
def dice_average_sets(y_true, y_pred):
assert y_true.shape[0]==y_pred.shape[0], "you should use same size data"
dice = []
for i in range(y_true.shape[0]):
dice.append(dice_coef(y_true[i], y_pred[i]))
print(np.mean(dice))
return dice
另外,我们也给出对应的Julia代码。
function dice_coef(y_true, y_pred)
smooth = 1
y_true_f = vec(y_true)
y_pred_f = vec(y_pred)
intersection = dot(y_true_f, y_pred_f)
return (2. * intersection + smooth) / (sum(y_true_f) + sum(y_pred_f) + smooth)
end
function DiceCoefficientAverage(y_true, y_pred)
if size(y_true)[1]!=size(y_pred)[1]
println("you should use same size data")
return -1
end
dice = []
for i in 1:size(y_true)[1]
append!(dice, dice_coef(y_true[i,:,:], y_pred[i,:,:]))
end
print(mean(dice))
end
实验
在一个针对前面提到的鱼类HTS图像分割问题。我们使用Julia和Python代码分别计算,发现python的代码竟然比Julia的快。
[1] Dice, Lee R. "Measures of the amount of ecologic association between species." Ecology 26.3 (1945): 297-302.
[2] Zou, Kelly H. et al. “Statistical validation of image segmentation quality based on a spatial overlap index.” Academic radiology 11 2 (2004): 178-89 .
[3] Ronneberger, Olaf, Philipp Fischer, and Thomas Brox. "U-net: Convolutional networks for biomedical image segmentation." International Conference on Medical image computing and computer-assisted intervention. Springer, Cham, 2015.
文章评论