当多张图片的mIOU分开计算求平均时,是先计算每张图片的mIOU,然后将这些mIOU相加再除以图片数量,得到最终的平均mIOU。这种方式适用于每张图片的对象类别和数量都不一样的情况,可以更准确地评估每张图片的分割性能。
而当多张图片的mIOU合并起来求平均时,是将所有图片的预测结果合并为一个大的分割结果,然后计算这个大的分割结果的mIOU。这种方式适用于每张图片的对象类别和数量相似,并且希望评估整体的分割性能。
因此,分开计算求平均和合并起来求平均的mIOU会得到不同的结果,选择哪种方式取决于具体的应用场景和评估需求。
单独计算
def compute_iou(pred_mask, true_mask):
intersection = np.logical_and(pred_mask, true_mask)
union = np.logical_or(pred_mask, true_mask)
iou = (np.sum(intersection) + 1e-6) / (np.sum(union) + 1e-6)
return iou
def compute_mean_iou(pred_images, true_images):
num_classes = 3 # 获取类别数
pred_images = np.eye(num_classes)[pred_images] # 进行One-Hot编码
true_images = np.eye(num_classes)[true_images] # 进行One-Hot编码
# print(pred_images.shape,true_images.shape)
mean_iou = 0.0
for i in range(num_classes):
pred_image = pred_images[:, :, i]
true_image = true_images[:, :, i]
iou = compute_iou(pred_image, true_image)
mean_iou += iou
mean_iou /= num_classes
return mean_iou
合并计算
class ConfusionMatrix(object):
def __init__(self, num_classes):
self.num_classes = num_classes
self.mat = None
def update(self, a, b):
n = self.num_classes
if self.mat is None:
# 创建混淆矩阵
self.mat = np.zeros((n, n), dtype=np.int64)
# 寻找GT中为目标的像素索引
k = (a >= 0) & (a < n)
# 统计像素真实类别a[k]被预测成类别b[k]的个数(这里的做法很巧妙)
inds = n * a[k] + b[k]
self.mat += np.bincount(inds, minlength=n ** 2).reshape(n, n)
def reset(self):
if self.mat is not None:
self.mat = None
def compute(self):
h = self.mat
# 计算全局预测准确率(混淆矩阵的对角线为预测正确的个数)
acc_global = np.diag(h).sum() / h.sum()
# 计算每个类别的准确率
acc = np.diag(h) / h.sum(1)
# 计算每个类别预测与真实目标的iou
iu = np.diag(h) / (h.sum(1) + h.sum(0) - np.diag(h))
return acc_global, acc, iu
def get_miou(self):
acc_global, acc, iu = self.compute()
return iu.mean().item()