图像分割评价指标:Dice和MIoU

2023-12-29 19:59

本文主要是介绍图像分割评价指标:Dice和MIoU,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • Dice
    • 理论
    • 代码
  • MIou
    • 理论
      • 查准率 precison
      • 查全率 recall
      • MIoU 平均交并比
    • 代码
      • 高效的矩阵运算
      • 低效的好理解的
      • 计算混淆矩阵
  • Dice和MIoU两者的关系
  • 参考链接

Dice

理论

Dice用来衡量预测结果pred和标签label的相似度,公式如下图所示,即两个集合的交集/并集。
在这里插入图片描述

注意:对于多分类的分割任务,网络的输出结果是多通道的,使用Dice计算准确度需要将标签转换为多通道的one_hot形式。

代码

def dice_acc(predict, label):"""计算多个batch的dicc@param predict: 模型预测值,Shape:[B, C, W, H]@param label: one_hot形式的标签,Shape:[B, C, W, H]"""batch_num, class_num = predict.shape[0: 2]assert predict.size() == label.size(), "the size of predict and target must be equal."# 计算交集intersection = (predict * label).reshape((batch_num, class_num, -1)).sum(dim=2)# 计算并集union = (predict + label).reshape((batch_num, class_num, -1)).sum(dim=2)dice = (2. * intersection + 1) / (union + 1)dice = dice.mean()# loss = 1 - dicereturn dice
  • 如果需要计算dice loss,只需要 1- dice_acc即可。
  • 可以借助torch.nn.functional.one_hot()函数将标签转化为one_hot形式。
  • 以上代码传入的predictlabel都是tensor,需要调用dice.item()只返回数值。

MIou

理论

为了计算MIoU,我们需要先引入混淆矩阵的概念。所谓混淆矩阵,就是真实结果和预测结果所组成的矩阵,将整个结果集划分为TPTNFPFN四类。
在这里插入图片描述

  • TP:True Positive 真正的正类,即label是正标签,predict也是正标签。
  • FN:False Negative 假的负类,即label是正标签,predict却预测是负标签。
  • FP:False Positive 假的正类,即label是负标签,predict却预测是正标签。
  • TN:True Negative 真正的负类,即label是负标签,predict也是负标签。

有了混淆矩阵后,我们可以在此基础上计算各种评价指标:

查准率 precison

在这里插入图片描述

查全率 recall

在这里插入图片描述

MIoU 平均交并比

在这里插入图片描述
上面的公式对应到混淆矩阵A上为 A(i, i) / A(i, : ) + A(:, j) - A(i, j),即对角线元素比上(对角线元素所在行和列的元素和 - 对角线元素)
在这里插入图片描述

注意:为了计算MIoU,我们需要把多通道的预测结果通过torch.argmax()函数转化为单通道的预测类别,然后和单通道的label计算交并比。

代码

为了计算MIoU,这里提供两种方式,一种是比较高效的矩阵运算,另一种是常规的好理解的但效率不高的方式,两者都可以用。

高效的矩阵运算

def miou(predict, label, class_num=3):"""计算多个batch的moiu@param predict: 模型预测值,Shape:[B, W, H]@param label: 标签,Shape:[B, W, H]"""batch = label.shape[0]predict, label = predict.flatten(), label.flatten()# 忽略背景的话就 >0k = (predict >= 0) & (predict < class_num)# 计算混淆矩阵hist = torch.bincount(class_num * predict[k].type(torch.int32) + label[k], minlength=batch * (class_num ** 2)).reshape(batch, class_num, class_num)# 将多个batch合并为一个,如果传入的参数没有batch这个维度,可以注释掉这句话hist = hist.sum(0)# 计算各个类的ioumiou = torch.diag(hist) / torch.maximum((hist.sum(1) + hist.sum(0) - torch.diag(hist)), torch.tensor(1))# 计算平均值mioureturn miou.mean()

低效的好理解的

def IOU(pred, target, n_classes = 3 ):"""计算miou@param predict: 模型预测值,Shape:[W, H]@param label: 标签,Shape:[W, H]"""ious = []# 从1开始,即忽略背景# 依次计算每个类for cls in range(1, n_classes):pred_inds = pred == clstarget_inds = target == cls# 计算两个集合在该类上的交集intersection = (pred_inds[target_inds]).sum()# 计算并集union = pred_inds.sum() + target_inds.sum() - intersectionif union == 0:ious.append(float('nan')) # If there is no ground truth,do not include in evaluationelse:ious.append(float(intersection.item()) / float(max(union.item(), 1)))# 计算多类的平均值 return torch.mean(torch.tensor(ious))

注意,这种的传入的参数是二维的,不能有batch维度。

计算混淆矩阵

这里提供一个计算混淆矩阵的快速实现,但很低效,仅供看看,实际还是要用上面torch.bincount计算混淆矩阵快。

# TP predict 和 label 同时为1
TP = ((pred1 == 1) & (label == 1)).cpu().sum()
# TN    predict 和 label 同时为0
TN = ((pred1 == 0) & (label == 0)).cpu().sum()
# FN    predict 0 label 1
FN = ((pred1 == 0) & (label == 1)).cpu().sum()
# FP    predict 1 label 0
FP = ((pred1 == 1) & (label == 0)).cpu().sum()

Dice和MIoU两者的关系

对于二分类的任务来说,二者思想都是交集/并集,但dice并不是在分母上减去交集,而是将交集在分子上算了两次

对于多分类来说,Dice是将预测结果转为了多通道,而MIoU只在一个通道上计算。

参考链接

https://www.jianshu.com/p/42939bf83b8a
https://blog.csdn.net/Pierce_KK/article/details/96505691
https://blog.csdn.net/lipengfei0427/article/details/109556985

这篇关于图像分割评价指标:Dice和MIoU的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/550554

相关文章

Python中OpenCV与Matplotlib的图像操作入门指南

《Python中OpenCV与Matplotlib的图像操作入门指南》:本文主要介绍Python中OpenCV与Matplotlib的图像操作指南,本文通过实例代码给大家介绍的非常详细,对大家的学... 目录一、环境准备二、图像的基本操作1. 图像读取、显示与保存 使用OpenCV操作2. 像素级操作3.

C/C++的OpenCV 进行图像梯度提取的几种实现

《C/C++的OpenCV进行图像梯度提取的几种实现》本文主要介绍了C/C++的OpenCV进行图像梯度提取的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录预www.chinasem.cn备知识1. 图像加载与预处理2. Sobel 算子计算 X 和 Y

c/c++的opencv图像金字塔缩放实现

《c/c++的opencv图像金字塔缩放实现》本文主要介绍了c/c++的opencv图像金字塔缩放实现,通过对原始图像进行连续的下采样或上采样操作,生成一系列不同分辨率的图像,具有一定的参考价值,感兴... 目录图像金字塔简介图像下采样 (cv::pyrDown)图像上采样 (cv::pyrUp)C++ O

Python+wxPython构建图像编辑器

《Python+wxPython构建图像编辑器》图像编辑应用是学习GUI编程和图像处理的绝佳项目,本教程中,我们将使用wxPython,一个跨平台的PythonGUI工具包,构建一个简单的... 目录引言环境设置创建主窗口加载和显示图像实现绘制工具矩形绘制箭头绘制文字绘制临时绘制处理缩放和旋转缩放旋转保存编

python+OpenCV反投影图像的实现示例详解

《python+OpenCV反投影图像的实现示例详解》:本文主要介绍python+OpenCV反投影图像的实现示例详解,本文通过实例代码图文并茂的形式给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一、前言二、什么是反投影图像三、反投影图像的概念四、反向投影的工作原理一、利用反向投影backproj

Python实现图片分割的多种方法总结

《Python实现图片分割的多种方法总结》图片分割是图像处理中的一个重要任务,它的目标是将图像划分为多个区域或者对象,本文为大家整理了一些常用的分割方法,大家可以根据需求自行选择... 目录1. 基于传统图像处理的分割方法(1) 使用固定阈值分割图片(2) 自适应阈值分割(3) 使用图像边缘检测分割(4)

使用Python实现图像LBP特征提取的操作方法

《使用Python实现图像LBP特征提取的操作方法》LBP特征叫做局部二值模式,常用于纹理特征提取,并在纹理分类中具有较强的区分能力,本文给大家介绍了如何使用Python实现图像LBP特征提取的操作方... 目录一、LBP特征介绍二、LBP特征描述三、一些改进版本的LBP1.圆形LBP算子2.旋转不变的LB

Python如何将大TXT文件分割成4KB小文件

《Python如何将大TXT文件分割成4KB小文件》处理大文本文件是程序员经常遇到的挑战,特别是当我们需要把一个几百MB甚至几个GB的TXT文件分割成小块时,下面我们来聊聊如何用Python自动完成这... 目录为什么需要分割TXT文件基础版:按行分割进阶版:精确控制文件大小完美解决方案:支持UTF-8编码

OpenCV图像形态学的实现

《OpenCV图像形态学的实现》本文主要介绍了OpenCV图像形态学的实现,包括腐蚀、膨胀、开运算、闭运算、梯度运算、顶帽运算和黑帽运算,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起... 目录一、图像形态学简介二、腐蚀(Erosion)1. 原理2. OpenCV 实现三、膨胀China编程(

C++字符串提取和分割的多种方法

《C++字符串提取和分割的多种方法》在C++编程中,字符串处理是一个常见的任务,尤其是在需要从字符串中提取特定数据时,本文将详细探讨如何使用C++标准库中的工具来提取和分割字符串,并分析不同方法的适用... 目录1. 字符串提取的基本方法1.1 使用 std::istringstream 和 >> 操作符示