图像分类、目标检测、语义分割、实例分割和全景分割的区别:::
https://blog.csdn.net/kk123k/article/details/86584216?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2allfirst_rank_v2~rank_v25-2-86584216.nonecase&utm_term=%E8%AF%AD%E4%B9%89%E5%88%86%E5%89%B2%E7%AE%97%E6%B3%95%E5%A6%82%E4%BD%95%E9%A2%84%E6%B5%8B%E6%8E%A9%E7%A0%81%E4%BD%8D%E7%BD%AE&spm=1000.2123.3001.4430
语义分割评价指标::
https://blog.csdn.net/qq_40234695/article/details/88633094?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2allfirst_rank_v2~rank_v25-3-88633094.nonecase&utm_term=%E8%AF%AD%E4%B9%89%E5%88%86%E5%89%B2%E7%AE%97%E6%B3%95%E5%A6%82%E4%BD%95%E9%A2%84%E6%B5%8B%E6%8E%A9%E7%A0%81%E4%BD%8D%E7%BD%AE&spm=1000.2123.3001.4430
当然看了一些语义分割的指标,也需要实现一下代码:
本文记录了语义分割准确性评价指标的总结以及代码实现
对于像素级别的分类,最常用的评价指标是Pixel Accuracy(像素准确率)和Mean Inetersection over Union(平均交并比),二者的计算都是建立在混淆矩阵的基础上的。因此首先来介绍一下混淆矩阵,之后分别介绍PA,MPA,MIoU,FWIoU,最后附上代码实现。
首先假定数据集中有n+1类(0~n+1),0通常表示背景。使用Pii表示原本为i类同时预测为i类,即真正(TP)和真负(TN), Pij表示原本为i类被预测为j类,即假正(FP)和假负(FN),如果第i类为正类,i!=j时,那么Pii表示TP,Pjj表示TN,Pij表示FP,Pji表示FN。
像素准确率(PA)
像素准确率是所有分类正确的像素数占像素总数的比例。公式化如下:
利用混淆矩阵计算则为(对角线元素之和除以矩阵所有元素之和)
平均像素准确率(MPA)
平均像素准确率是分别计算每个类别分类正确的像素数占所有预测为该类别像素数的比例,即精确率,然后累加求平均。公式化如下:
利用混淆矩阵计算公式为(每一类的精确率Pi都等于对角线上的TP除以对应列的像素数)
平均交并比(mloU)
平均交并比是对每一类预测的结果和真实值的交集与并集的比值求和平均的结果。公式化如下
IoU利用混淆矩阵计算:
解释如下:
如图所示,仅仅针对某一类来说,红色部分代表真实值,真实值有两部分组成TP,FN;黄色部分代表预测值,预测值有两部分组成TP,FP;白色部分代表TN(真负);
所以他们的交集就是TP+FP+FN,并集为TP
频权交并比(FWloU)
频权交并比是根据每一类出现的频率设置权重,权重乘以每一类的IoU并进行求和。公式化如下:
利用混淆矩阵计算:每个类别的真实数目为TP+FN,总数为TP+FP+TN+FN,其中每一类的权重和其IoU的乘积计算公式如下,在将所有类别的求和即可
代码实现:
#https://blog.csdn.net/kkkkk0826/article/details/102962168 代码连接地址
import numpy as np
from PIL import Image
import cv2
__all__ = ['SegmentationMetric']
"""
confusionMetric
P\L P N
P TP FP
N FN TN
"""
class SegmentationMetric(object):
def __init__(self, numClass):
self.numClass = numClass
self.confusionMatrix = np.zeros((self.numClass,) * 2)
def pixelAccuracy(self):
# return all class overall pixel accuracy
# acc = (TP + TN) / (TP + TN + FP + TN)
acc = np.diag(self.confusionMatrix).sum() / self.confusionMatrix.sum()
return acc
def classPixelAccuracy(self):
# return each category pixel accuracy(A more accurate way to call it precision)
# acc = (TP) / TP + FP
classAcc = np.diag(self.confusionMatrix) / self.confusionMatrix.sum(axis=1)
return classAcc
def meanPixelAccuracy(self):
classAcc = self.classPixelAccuracy()
meanAcc = np.nanmean(classAcc)
return meanAcc
def meanIntersectionOverUnion(self):
# Intersection = TP Union = TP + FP + FN
# IoU = TP / (TP + FP + FN)
intersection = np.diag(self.confusionMatrix)
union = np.sum(self.confusionMatrix, axis=1) + np.sum(self.confusionMatrix, axis=0) - np.diag(
self.confusionMatrix)
IoU = intersection / union
mIoU = np.nanmean(IoU)
return mIoU
def genConfusionMatrix(self, imgPredict, imgLabel):
# remove classes from unlabeled pixels in gt image and predict
mask = (imgLabel >= 0) & (imgLabel < self.numClass)
label = self.numClass * imgLabel[mask] + imgPredict[mask]
count = np.bincount(label, minlength=self.numClass ** 2)
confusionMatrix = count.reshape(self.numClass, self.numClass)
return confusionMatrix
def Frequency_Weighted_Intersection_over_Union(self):
# FWIOU = [(TP+FN)/(TP+FP+TN+FN)] *[TP / (TP + FP + FN)]
freq = np.sum(self.confusion_matrix, axis=1) / np.sum(self.confusion_matrix)
iu = np.diag(self.confusion_matrix) / (
np.sum(self.confusion_matrix, axis=1) + np.sum(self.confusion_matrix, axis=0) -
np.diag(self.confusion_matrix))
FWIoU = (freq[freq > 0] * iu[freq > 0]).sum()
return FWIoU
def addBatch(self, imgPredict, imgLabel):
assert imgPredict.shape == imgLabel.shape
self.confusionMatrix += self.genConfusionMatrix(imgPredict, imgLabel)
def reset(self):
self.confusionMatrix = np.zeros((self.numClass, self.numClass))
if __name__ == '__main__':
ppath="D:/1/fcn_segment/test/precdict/10-p.png" # 用PIL中的Image.open打开图像
mpath= "D:/1/fcn_segment/test/mask1/10-m.png"
imgPredict =cv2.imread(ppath) # 转化成numpy数组
imgLabel = cv2.imread(mpath)
print("imgPredict:", imgPredict.shape)
print("imgPredict:", type(imgPredict))
print("imgLabel:", imgLabel.shape)
print("imgLabel:", type(imgLabel))
metric = SegmentationMetric(256)
metric.addBatch(imgPredict, imgLabel)
acc = metric.pixelAccuracy() #pa 像素准确率
mIoU = metric.meanIntersectionOverUnion() #平均像素准确率
print(acc, mIoU)
连接:https://blog.csdn.net/sinat_29047129/article/details/103642140?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2allfirst_rank_v2~rank_v25-4-103642140.nonecase&utm_term=resnet34%E5%88%86%E7%B1%BB%E5%87%86%E7%A1%AE%E7%8E%87&spm=1000.2123.3001.4430
是对上面的一个小总结。这个代码说明一下遇到的坑,首先可以用两张图像去对比,然后你这个图像不一定保证是像素是0-255之间的对吧,这样你可以输入
if __name__ == '__main__':
ppath="D:/1/fcn_segment/test/predict1/2-p.png" # 用PIL中的Image.open打开图像
mpath= "D:/1/fcn_segment/test/mask1/2-m.png" #D:/1/fcn_segment/test/predict1/5-p.png
imgPredict =cv2.imread(ppath) # 转化成numpy数组
imgLabel = cv2.imread(mpath)
print("imgPredict:", imgPredict.shape)
print("imgPredict:", type(imgPredict))
print("imgLabel:", imgLabel.shape)
print("imgLabel:", type(imgLabel))
metric = SegmentationMetric(256) #3表示有3个分类,有几个分类就填几
metric.addBatch(imgPredict, imgLabel)
pa = metric.pixelAccuracy() #pa 像素准确率
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)
这个256,必须是256,代表0-255这么多像素之间,你的两个图片去对比值一样不一样。通过看博客,你会发现别人也有这个问题,具体解答我也再博客留言地方回答了咋解决这个问题,其实也不用解决。。。就是 方法不一样而已,结果是正确的,cpa矩阵输出是256个值 其中其他无用的值是nan !! 你也可以,把输入的两个图统一规定只有二值化,0和1,这样图看起来就是黑色的。。。以为人眼看不见1这个像素值。。。这样你可以把 metric = SegmentationMetric(2) 这样就对了 结果还是一样 cpa显示的矩阵只有两个值了。
链接:https://blog.csdn.net/zsc201825/article/details/93487506?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.edu_weight&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.edu_weight
举例子的形式讲述这些指标值,其中acc和precises并不一样。细看
链接:https://blog.csdn.net/weixin_42990464/article/details/105339266?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.edu_weight&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.edu_weight
给出了iou miou f1 kappa的代码实现。
连接:https://blog.csdn.net/zichen_ziqi/article/details/80408465
这个讲的很好,给了代码,matlab和py都可以跑通,建议看这个连接。其中有roc曲线和结果。
可以换自己的数据集。