1. 程式人生 > 程式設計 >python實現交併比IOU教程

python實現交併比IOU教程

交併比(Intersection-over-Union,IoU),目標檢測中使用的一個概念,是產生的候選框(candidate bound)與原標記框(ground truth bound)的交疊率,即它們的交集與並集的比值。最理想情況是完全重疊,即比值為1。

python實現交併比IOU教程

計算公式:

python實現交併比IOU教程

Python實現程式碼:

def cal_iou(box1,box2):
 """
 :param box1: = [xmin1,ymin1,xmax1,ymax1]
 :param box2: = [xmin2,ymin2,xmax2,ymax2]
 :return: 
 """
 xmin1,ymax1 = box1
 xmin2,ymax2 = box2
 # 計算每個矩形的面積
 s1 = (xmax1 - xmin1) * (ymax1 - ymin1) # C的面積
 s2 = (xmax2 - xmin2) * (ymax2 - ymin2) # G的面積
 
 # 計算相交矩形
 xmin = max(xmin1,xmin2)
 ymin = max(ymin1,ymin2)
 xmax = min(xmax1,xmax2)
 ymax = min(ymax1,ymax2)
 
 w = max(0,xmax - xmin)
 h = max(0,ymax - ymin)
 area = w * h # C∩G的面積
 iou = area / (s1 + s2 - area)
 return iou
# -*-coding: utf-8 -*-
"""
 @Project: IOU
 @File : IOU.py
 @Author : panjq
 @E-mail : [email protected]
 @Date : 2018-10-14 10:44:06
"""
def calIOU_V1(rec1,rec2):
 """
 computing IoU
 :param rec1: (y0,x0,y1,x1),which reflects
   (top,left,bottom,right)
 :param rec2: (y0,x1)
 :return: scala value of IoU
 """
 # 計算每個矩形的面積
 S_rec1 = (rec1[2] - rec1[0]) * (rec1[3] - rec1[1])
 S_rec2 = (rec2[2] - rec2[0]) * (rec2[3] - rec2[1])
 
 # computing the sum_area
 sum_area = S_rec1 + S_rec2
 
 # find the each edge of intersect rectangle
 left_line = max(rec1[1],rec2[1])
 right_line = min(rec1[3],rec2[3])
 top_line = max(rec1[0],rec2[0])
 bottom_line = min(rec1[2],rec2[2])
 
 # judge if there is an intersect
 if left_line >= right_line or top_line >= bottom_line:
  return 0
 else:
  intersect = (right_line - left_line) * (bottom_line - top_line)
  return intersect/(sum_area - intersect)
 
def calIOU_V2(rec1,x1)
 :return: scala value of IoU
 """
 # cx1 = rec1[0]
 # cy1 = rec1[1]
 # cx2 = rec1[2]
 # cy2 = rec1[3]
 # gx1 = rec2[0]
 # gy1 = rec2[1]
 # gx2 = rec2[2]
 # gy2 = rec2[3]
 cx1,cy1,cx2,cy2=rec1
 gx1,gy1,gx2,gy2=rec2
 # 計算每個矩形的面積
 S_rec1 = (cx2 - cx1) * (cy2 - cy1) # C的面積
 S_rec2 = (gx2 - gx1) * (gy2 - gy1) # G的面積
 
 # 計算相交矩形
 x1 = max(cx1,gx1)
 y1 = max(cy1,gy1)
 x2 = min(cx2,gx2)
 y2 = min(cy2,gy2)
 
 w = max(0,x2 - x1)
 h = max(0,y2 - y1)
 area = w * h # C∩G的面積
 
 iou = area / (S_rec1 + S_rec2 - area)
 return iou
 
if __name__=='__main__':
 rect1 = (661,27,679,47)
 # (top,right)
 rect2 = (662,682,47)
 iou1 = calIOU_V1(rect1,rect2)
 iou2 = calIOU_V2(rect1,rect2)
 print(iou1)
 print(iou2)
 

參考:https://www.jb51.net/article/184542.htm

補充知識:Python計算多分類的混淆矩陣,Precision、Recall、f1-score、mIOU等指標

直接上程式碼,一看很清楚

import os
import numpy as np
from glob import glob
from collections import Counter
 
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 metrics(confu_mat_total,save_path=None):
 '''
 :param confu_mat: 總的混淆矩陣
 backgound:是否幹掉背景
 :return: txt寫出混淆矩陣,precision,recall,IOU,f-score
 '''
 class_num = confu_mat_total.shape[0]
 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 = [] # 識別中每類分類正確的個數
 
 for i in range(class_num):
  TP.append(confu_mat[i,i])
 
 # 計算f1-score
 TP = np.array(TP)
 FN = col_sum - TP
 FP = raw_sum - TP
 
 # 計算並寫出precision,recall,f1-score,f1-m以及mIOU
 
 f1_m = []
 iou_m = []
 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)
 
 f1_m = np.array(f1_m)
 iou_m = np.array(iou_m)
 if save_path is not None:
  with open(save_path + 'accuracy.txt','w') as f:
   f.write('OA:\t%.4f\n' % (oa*100))
   f.write('kappa:\t%.4f\n' % (kappa*100))
   f.write('mf1-score:\t%.4f\n' % (np.mean(f1_m)*100))
   f.write('mIou:\t%.4f\n' % (np.mean(iou_m)*100))
 
   # 寫出precision
   f.write('precision:\n')
   for i in range(class_num):
    f.write('%.4f\t' % (float(TP[i]/raw_sum[i])*100))
   f.write('\n')
 
   # 寫出recall
   f.write('recall:\n')
   for i in range(class_num):
    f.write('%.4f\t' % (float(TP[i] / col_sum[i])*100))
   f.write('\n')
 
   # 寫出f1-score
   f.write('f1-score:\n')
   for i in range(class_num):
    f.write('%.4f\t' % (float(f1_m[i])*100))
   f.write('\n')
 
   # 寫出 IOU
   f.write('Iou:\n')
   for i in range(class_num):
    f.write('%.4f\t' % (float(iou_m[i])*100))
   f.write('\n')

以上這篇python實現交併比IOU教程就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。