通过计算各张影像总的混淆矩阵,然后一一计算OA、Kappa、precision、recall、F1-score、IOU
(注意之前写的代码,公式有处,这里更新如下)
下面直接上菜,谢谢品尝!
- import cv2 as cv
- import numpy as np
- from collections import Counter
- import xlwt as excel
- from decimal import Decimal
- def cal_confu_matrix(label, predict, class_num):
- confu_list = []
- for i in range(class_num):
- c = Counter(predict[np.where(label == i)])
- single_row = []
- for j in range(class_num):
- single_row.append(c[j])
- confu_list.append(single_row)
- return np.array(confu_list).astype(np.int32)
- def metric_evaluate(confu_mat_total, save_path, save_name):
- '''
- :param confu_mat: 总的混淆矩阵
- :return: excel写出混淆矩阵, precision,recall,IOU,f-score
- '''
- class_num = confu_mat_total.shape[0]
- file = excel.Workbook(encoding='utf-8')
- table_name = save_name
- pic_name = table_name + ' metrics:'
- table = file.add_sheet(table_name)
- table_raw = 0 # 表从第一行开始记录数据
- table.write(table_raw, 0, pic_name)
- table_raw += 2
- '''计算归一化到0-1的混淆矩阵;并写出到Excel中'''
- confu_mat = confu_mat_total.astype(np.float32) + 0.0001
- col_sum = np.sum(confu_mat, axis=1) # 按行求和
- raw_sum = np.sum(confu_mat, axis=0) # 每一列的数量
- '''计算各类面积比,以求OA值'''
- oa = 0
- for i in range(class_num):
- oa = oa + confu_mat[i, i]
- oa = oa / confu_mat.sum()
- '''Kappa'''
- pe_fz = 0
- for i in range(class_num):
- pe_fz += col_sum[i] * raw_sum[i]
- pe = pe_fz / (np.sum(confu_mat) * np.sum(confu_mat))
- kappa = (oa - pe) / (1 - pe)
- # 将混淆矩阵写入excel中
- TP = [] # 识别中每类分类正确的个数
- table.write(table_raw, 0, 'confusion_matrix:')
- table_raw = table_raw + 1
- name_str = ['Clutter/background', 'Impervious surfaces', 'Building', 'Low vegetation', 'Tree', 'Car']
- for i in range(class_num):
- table.write(table_raw, 1+i, name_str[i])
- for i in range(class_num):
- table_raw = table_raw + 1
- table.write(table_raw, 0, name_str[i])
- TP.append(confu_mat[i, i])
- for j in range(class_num):
- table.write(table_raw, j + 1, int(confu_mat_total[i, j]))
- # 计算f1-score
- TP = np.array(TP)
- FN = raw_sum - TP
- FP = col_sum - TP
- # 计算并写出precision,recall, f1-score,f1-m以及mIOU
- table_raw = table_raw + 2
- table.write(table_raw, 0, 'precision:')
- # 写出precision
- for i in range(class_num):
- table.write(table_raw, i + 1, Decimal(float(TP[i]/raw_sum[i])).quantize(Decimal("0.000")))
- table_raw += 1
- table.write(table_raw, 0, 'Recall:')
- # 写出recall
- for i in range(class_num):
- table.write(table_raw, i + 1, Decimal(float(TP[i]/col_sum[i])).quantize(Decimal("0.000")))
- f1_m = []
- iou_m = []
- table_raw += 1
- table.write(table_raw, 0, 'f1-score:')
- for i in range(class_num):
- # 写出f1-score
- f1 = TP[i] * 2 / (TP[i] * 2 + FP[i] + FN[i])
- f1_m.append(f1)
- iou = TP[i] / (TP[i] + FP[i] + FN[i])
- iou_m.append(iou)
- table.write(table_raw, i + 1, Decimal(f1).quantize(Decimal("0.000")))
- table_raw += 1
- table.write(table_raw, 0, 'OA:')
- table.write(table_raw, 1, Decimal(float(oa)).quantize(Decimal("0.000")))
- table_raw += 1
- table.write(table_raw, 0, 'Kappa:')
- table.write(table_raw, 1, Decimal(float(kappa)).quantize(Decimal("0.000")))
- f1_m = np.array(f1_m)
- table_raw += 1
- table.write(table_raw, 0, 'f1-m:')
- table.write(table_raw, 1, Decimal(float(np.mean(f1_m))).quantize(Decimal("0.000")))
- iou_m = np.array(iou_m)
- table_raw += 1
- table.write(table_raw, 0, 'mIOU:')
- table.write(table_raw, 1, Decimal(float(np.mean(iou_m))).quantize(Decimal("0.000")))
- file.save(save_path + table_name + '.xls')