拉萨市建材网络科技有限公司
首页 | 联系方式 | 加入收藏 | 设为首页 | 手机站

产品目录

联系方式

联系人:业务部
电话: 00165-55511
邮箱:service@ydkmjgds.com

当前位置:首页 >> 产品展示 >> 默认分类 >> 正文

numpy图像语义分隔评估实现

详细信息:

在做图像语言分隔的时候,我们往往需要计算出像素精确度,交并比等值来评估我们的算法或者神经网络的表现。本篇文章着重介绍如何用numpy实现像素精确度、平均像素精确度、平均交并比和加权的交并比的计算。

在正式开始之前需要先掌握几个numpy的函数和编程技巧。

bincount函数

功能:实现个数的统计。

示例:假设有numpy数组:

x = np.array([0, 1, 1, 3, 2, 1, 7])

我们想要知道里面0~7这8个数出现的次数是多少,就可以用bincount函数。

y=np.bincount(x)

打印出y得到[1 3 1 1 0 0 0 1],意思是我们有0~7这8个数,按照数组下标排列起来,然后对应的数值则为0~7出现的次数。

需要注意的是这里的数值长度是函数自己给的,也就是说它只会统计到我们放进函数的这个数组中最大的那个值。如果我们想要统计0~9这10个数出现的次数,我们可以通过指定minlength参数实现:

y = np.bincount(x,minlength=10)

输出则为:[1 3 1 1 0 0 0 1 0 0]

diag函数

功能:取出对角线上的值。

示例:假设有numpy数组:

x=np.array([(1,0,0,0,0,4),(0,2,0,2,0,0),(0,0,3,0,0,4),(0,0,4,4,0,0),(0,0,5,0,5,4),(0,0,0,2,0,6)])

[[1 0 0 0 0 4]
[0 2 0 2 0 0]
[0 0 3 0 0 4]
[0 0 4 4 0 0]
[0 0 5 0 5 4]
[0 0 0 2 0 6]]

我们想要取出对角线上的数,则可以用diag函数。

y=np.diag(x)

输出为:[1 2 3 4 5 6]

如果我们想要把对角线上的数加起来,则写成:

y=np.diag(x).sum()

输出为:21

zip函数

功能:依据多维数组的第一维进行遍历。

示例:假设有numpy数组:

x=np.array([[(0,0,0,0,0,4), (0,0,0,2,0,0)],[(0,0,0,0,0,4), (0,0,0,2,0,0)]])
y=np.array([[(0,0,0,0,0,4), (0,0,0,2,0,0)],[(0,0,0,0,0,1), (0,0,0,2,0,0)]])

它们的形状是:(2, 2, 6)

假设前面的2指代的是不同的图片,而后面的2和6指代的是图片的宽和高 ,而我们希望将图片一张张取出来进行计算,则可以用zip函数来做。

for onex, oney in zip(x, y):
 print(onex.shape)
 print(oney.shape)
flatten函数

功能:将多维数组直接转化成1维

示例:假设有numpy数组:

x=np.array([[(0,0,0,0,0,4), (0,0,0,2,0,0)],[(0,0,0,0,0,4), (0,0,0,2,0,0)]])

我们希望把数组转为1维的,则可以用flatten函数。

y=x.flatten()

输出为:[0 0 0 0 0 4 0 0 0 2 0 0 0 0 0 0 0 4 0 0 0 2 0 0]

数组感兴趣区域选取

功能:选取感兴趣值进行计算,其他非感兴趣区域置为0

示例:假设有numpy数组:

x = np.array([0, 1, 1, 3, 2, 1, 7])

我们只想计算0~2这个3个数,而无视其他的数,则可以用如下代码实现:

mask = (x >= 0) & (x <= 2)
x=x[mask]

输出为:[0 1 1 2 1]

可以看到,非感兴趣区域被删除掉了。

上面就是所有需要先掌握的点,下面直接放出图像语义分隔评估的实现代码

import numpy as np
# 精确度计算
def _fast_hist(label_true, label_pred, n_class):
 #标注计算类别范围以内的数,不在范围内的不考虑
 mask = (label_true >= 0) & (label_true < n_class)
 # 经过这句话的处理,行数将代表标签的值,而列数将代表预测的值,而具体的值代表个数。
 # 也就是说,对角线上的数分别指代第n个类别中,预测值和标签值相同的个数
 hist = np.bincount(n_class * label_true[mask].astype(int) +label_pred[mask], 
 minlength=n_class ** 2).reshape(n_class, n_class)
 return hist
def label_accuracy_score(label_trues, label_preds, n_class):
 """Returns accuracy score evaluation result.
 - overall accuracy
 - mean accuracy
 - mean IU
 - fwavacc
 """
 hist = np.zeros((n_class, n_class))
 #将标签和预测图像按行放入函数中
 for lt, lp in zip(label_trues, label_preds):
 hist += _fast_hist(lt.flatten(), lp.flatten(), n_class)
 acc = np.diag(hist).sum() / hist.sum()#总体精确度计算
 acc_cls = np.diag(hist) / hist.sum(axis=1)#求得每一类像素精确度的平均值
 acc_cls = np.nanmean(acc_cls)#求得总体平均精确度
 iu = np.diag(hist) / (hist.sum(axis=1) + hist.sum(axis=0) - np.diag(hist))#按类别求得交并比
 mean_iu = np.nanmean(iu)#求得总体平均交并比
 freq = hist.sum(axis=1) / hist.sum()#求得标签中各个类别所占的比例
 fwavacc = (freq[freq > 0] * iu[freq > 0]).sum()#按权值计算交并比
 return acc, acc_cls, mean_iu, fwavacc
label_true=np.array([[(0,0,0,0,0,4), (0,0,0,2,0,0)],[(0,0,0,0,0,4), (0,0,0,2,0,0)]])
label_pred=np.array([[(0,0,0,0,0,4), (0,0,0,2,0,0)],[(0,0,0,0,0,1), (0,0,0,2,0,0)]])
train_acc = 0
train_acc_cls = 0
train_mean_iu = 0 
train_fwavacc = 0
#用zip可以遍历多维数组的第一个维度,在本应用中每次返回一张标签和一张预测图像
for lbt, lbp in zip(label_true, label_pred):
 acc, acc_cls, mean_iu, fwavacc = label_accuracy_score(lbt, lbp, 5)#5为要计算的类别总数,也就是0~4
 train_acc += acc
 train_acc_cls += acc_cls
 train_mean_iu += mean_iu
 train_fwavacc += fwavacc