MIOU定义
有很多博客都有写MIOU,参考下面文章
注意点:
- 类别包含背景,二分类也包含背景
- 混淆矩阵就是分别统计分类模型归错类,归对类的观测值个数,然后把结果放在一个表里展示出来。
代码实现
"""
refer to https://github.com/jfzhang95/pytorch-deeplab-xception/blob/master/utils/metrics.py
"""
import numpy as np
# 设标签宽W,长H
def fast_hist(a, b, n): # a是转化成一维数组的标签,形状(H×W,);b是转化成一维数组的预测特征图,形状(H×W,);n是类别数目
k = (a >= 0) & (a < n) # k是一个一维bool数组,形状(H×W,);目的是找出标签中需要计算的类别(去掉了背景),假设0是背景
out = np.bincount(n * a[k].astype(int) + b[k], minlength=n ** 2).reshape(n, n)
return out
def per_class_iu(hist): # 分别为每个类别(在这里是19类)计算mIoU,hist的形状(n, n)
out = np.diag(hist) / (hist.sum(1) + hist.sum(0) - np.diag(hist)) # 矩阵的对角线上的值组成的一维数组/矩阵的所有元素之和,返回值形状(n,)
return out
def compute_mIoU(pred, label, n_classes=2):
hist = np.zeros((n_classes, n_classes)) # hist初始化为全零,在这里的hist的形状是[n_classes, n_classes]
hist += fast_hist(label.flatten(), pred.flatten(), n_classes) # 对一张图片计算 n_classes×n_classes 的hist矩阵,并累加
mIoUs = per_class_iu(hist) # 计算逐类别mIoU值
print('mIOUs', mIoUs)
for ind_class in range(n_classes): # 逐类别输出一下mIoU值
print(str(round(mIoUs[ind_class] * 100, 2)))
print('===> mIoU: ' + str(round(np.nanmean(mIoUs) * 100, 2))) # 在所有验证集图像上求所有类别平均的mIoU值,计算时忽略NaN值
return mIoUs
if __name__ == '__main__':
imgPredict = np.array([0, 0, 1, 0, 0, 0, 0, 0, 1]) # 可直接换成预测图片
imgLabel = np.array([0, 1, 1, 0, 0, 0, 0, 0, 1]) # 可直接换成标注图片
compute_mIoU(imgPredict, imgLabel)
# metric = SegmentationMetric(3) # 3表示有3个分类,有几个分类就填几
# metric.addBatch(imgPredict, imgLabel)
# pa = metric.pixelAccuracy()
# cpa = metric.classPixelAccuracy()
# mpa = metric.meanPixelAccuracy()
# mIoU = metric.meanIntersectionOverUnion()
# print('pa is : %f' % pa)
# print('cpa is :') # 列表
# print(cpa)
# print('mpa is : %f' % mpa)
# print('mIoU is : %f' % mIoU)
参考博客
[1]:语义分割之MIoU原理与实现
[2]:4.4.2分类模型评判指标(一) - 混淆矩阵(Confusion Matrix)
[3]:核心这一篇:深度学习计算机视觉图像分割领域指标mIoU(平均交并比)计算代码与逐行解析