正常矩形计算IOU与与NMS,多边形计算IOU
生活随笔
收集整理的這篇文章主要介紹了
正常矩形计算IOU与与NMS,多边形计算IOU
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一.計算IOU
def intersect(box_a, box_b):max_xy = np.minimum(box_a[:, 2:], box_b[2:])min_xy = np.maximum(box_a[:, :2], box_b[:2])inter = np.clip((max_xy - min_xy), a_min=0, a_max=np.inf)return inter[:, 0] * inter[:, 1]def jaccard_numpy(box_a, box_b):"""Compute the jaccard overlap of two sets of boxes. The jaccard overlapis simply the intersection over union of two boxes.E.g.:Args:box_a: Multiple bounding boxes, Shape: [num_boxes,4]box_b: Single bounding box, Shape: [4]Return:jaccard overlap: Shape: [box_a.shape[0], box_a.shape[1]]"""inter = intersect(box_a, box_b)area_a = ((box_a[:, 2]-box_a[:, 0]) *(box_a[:, 3]-box_a[:, 1])) # [A,B]area_b = ((box_b[2]-box_b[0]) *(box_b[3]-box_b[1])) # [A,B]union = area_a + area_b - interreturn inter / union # [A,B]人工修正后的每一個框與算法輸出的所有框去計算IOU,取出IOU大于0.9的算法輸出框
def compute_IOU(algrim_bboxs,fix_bboxs):# print('algrim_bboxs:', algrim_bboxs)# print('fix_bboxs:', fix_bboxs)for i, fix_bbox in enumerate(fix_bboxs):print('fix_bbox:', fix_bbox)fix_x1, fix_y1, fix_x2, fix_y2 = fix_bboxx1, y1, x2, y2 = algrim_bboxs[:,0], algrim_bboxs[:,1], algrim_bboxs[:,-2], algrim_bboxs[:,-1]area = (y2-y1)*(x2-x1)inter = np.maximum((np.minimum(x2,fix_x2) - np.maximum(x1,fix_x1)),0)*np.maximum((np.minimum(y2,fix_y2) - np.maximum(y1, fix_y1)),0)union = area+(fix_y2-fix_y1)*(fix_x2-fix_x1)-interIOU = inter/union# print('IOU:', IOU)index = np.where(IOU > 0.9)[0]print('algrim_bboxs[index]:', algrim_bboxs[index])?
注釋:下面的代碼假設了第0行是IOU最大的,那么其余做NMS計算
boxes=np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]]) y1 = boxes[:, 0] x1 = boxes[:, 1] y2 = boxes[:, 2] x2 = boxes[:, 3] area = (y2 - y1) * (x2 - x1) print('area=',area) box_area=area[0] print('box_area=',box_area) boxes_area=area[1:] print('boxes_area=',boxes_area) box=boxes[0] y1 = np.maximum(box[0], boxes[1:, 0]) y2 = np.minimum(box[2], boxes[1:, 2]) x1 = np.maximum(box[1], boxes[1:, 1]) x2 = np.minimum(box[3], boxes[1:, 3]) #注意與0判斷 若不想交返回0值,即intersection為0 intersection = np.maximum(x2 - x1, 0) * np.maximum(y2 - y1, 0) print('intersection=',intersection) union = box_area + boxes_area - intersection[:] print('union=',union) iou = intersection / union print('iou=',iou)二,一般加上score,這樣用
scores = np.array([0.5, 0.7, 0.3, 0.2]) ixs=scores.argsort()[::-1] print('ixs=',ixs) boxes=np.array([[1,2,3,4],[1.2, 0.4,2.1, 0.8],[5,6,7,8],[9,10,11,12]]) y1 = boxes[:, 0] x1 = boxes[:, 1] y2 = boxes[:, 2] x2 = boxes[:, 3] area = (y2 - y1) * (x2 - x1) print('area=',area) box_area=area[ixs[0]] print('box_area=',box_area) boxes_area=area[ixs[1:]] print('boxes_area=',boxes_area) box=boxes[ixs[0]] boxes=boxes[ixs[1:]] y1 = np.maximum(box[0], boxes[:, 0]) y2 = np.minimum(box[2], boxes[:, 2]) x1 = np.maximum(box[1], boxes[:, 1]) x2 = np.minimum(box[3], boxes[:, 3]) #注意與0判斷 若不想交返回0值,即intersection為0 intersection = np.maximum(x2 - x1, 0) * np.maximum(y2 - y1, 0) print('intersection=',intersection) union = box_area + boxes_area - intersection[:] print('union=',union) iou = intersection / union print('iou=',iou)三,求其NMS后的框的小trick
scores=np.array([0.8,0.4,0.7,0.2,0.5]) ixs = scores.argsort()[::-1] print('ixs=',ixs) #iou要比score少一個數值,因為iou的計算是由score的第一個值確定的,故下面的np.where要加1 iou=np.array([0.3,0.6,0.1,0.4]) threshold=0.3 remove_ixs = np.where(iou > threshold)[0]+1 print('remove_ixs=',remove_ixs) # Remove indices of the picked and overlapped boxes. ixs = np.delete(ixs, remove_ixs) print('ixs=',ixs) ixs = np.delete(ixs, 0) print('ixs=',ixs)四,加入while,就把不要的框刪掉
scores = np.array([0.8, 0.4, 0.7, 0.2, 0.5]) ixs = scores.argsort()[::-1] while len(ixs) > 0:print('================================')print('ixs=', ixs)# iou要比score少一個數值,因為iou的計算是由score的第一個值確定的,故下面的np.where要加1iou = np.array([0.3, 0.6, 0.1, 0.4])threshold = 0.3remove_ixs = np.where(iou > threshold)[0] + 1print('remove_ixs=', remove_ixs)# Remove indices of the picked and overlapped boxes.ixs = np.delete(ixs, remove_ixs)print('ixs=', ixs)ixs = np.delete(ixs, 0)print('ixs=', ixs)五,faster rcnn NMS
def py_cpu_nms(dets, thresh):"""Pure Python NMS baseline."""x1 = dets[:, 0]y1 = dets[:, 1]x2 = dets[:, 2]y2 = dets[:, 3]scores = dets[:, 4]areas = (x2 - x1 + 1) * (y2 - y1 + 1)order = scores.argsort()[::-1]print('order',order)keep = []while order.size > 0:i = order[0]keep.append(i)xx1 = np.maximum(x1[i], x1[order[1:]])yy1 = np.maximum(y1[i], y1[order[1:]])xx2 = np.minimum(x2[i], x2[order[1:]])yy2 = np.minimum(y2[i], y2[order[1:]])w = np.maximum(0.0, xx2 - xx1 + 1)h = np.maximum(0.0, yy2 - yy1 + 1)inter = w * hovr = inter / (areas[i] + areas[order[1:]] - inter)print('ovr=',ovr)print('np.where(ovr <= thresh)',np.where(ovr <= thresh))inds = np.where(ovr <= thresh)[0]print('inds=',inds)print('inds + 1',inds + 1)print('order[inds + 1]',order[inds + 1])order = order[inds + 1]print('order=',order)return keep def nms():# ###self nmsresult = [np.array([[7.9301813e+02, 6.3052429e+02, 8.9795898e+02, 7.2513965e+02,9.9307442e-01],[8.0682990e+02, 6.4606281e+02, 8.7198071e+02, 7.1328979e+02,9.5732883e-02]], dtype=np.float32)]##faster rcnn nmskeep=py_cpu_nms(result[0],0.7)print('keep=',keep)for i in keep:print('i=',i)print(result[0][i])此處大于0.7IOU的框就抑制, 小于0.7的就留下.
六.多邊形利用polygon計算IOU
def compute_IOU_():import numpy as npimport shapelyfrom shapely.geometry import Polygon, MultiPoint # 多邊形path = './134.jpg'img = cv2.imread(path)print('img.shape:', img.shape)line1 = [728, 252, 908, 215, 934, 312, 752, 355] # 四邊形四個點坐標的一維數組表示,[x,y,x,y....]line2 = [741, 262, 907, 228, 923, 308, 758, 342]# #debug to show# line1 = np.array(line1).reshape(4, 2)# line2 = np.array(line2).reshape(4, 2)# cv2.polylines(img, [np.array(line1).reshape(-1, 1, 2)], True, (0, 255, 0), thickness=2)# cv2.polylines(img, [np.array(line2).reshape(-1, 1, 2)], True, (0, 0, 255), thickness=2)# cv2.imwrite('134_with_rect.jpg',img)line1_box = np.array(line1).reshape(4, 2) # 四邊形二維坐標表示# 凸多邊形# poly1 = Polygon(line1_box).convex_hull#凸多邊形與凹多邊形poly1 = Polygon(line1_box)#.convex_hull # python四邊形對象,會自動計算四個點,最后四個點順序為:左上 左下 右下 右上 左上print(Polygon(line1_box).convex_hull)line2_box = np.array(line2).reshape(4, 2)# 凸多邊形# poly2 = Polygon(line2_box).convex_hull# 凸多邊形與凹多邊形poly2 = Polygon(line2_box)print(Polygon(line2_box).convex_hull)union_poly = np.concatenate((line1_box, line2_box)) # 合并兩個box坐標,變為8*2# print(union_poly)print(MultiPoint(union_poly).convex_hull) # 包含兩四邊形最小的多邊形點if not poly1.intersects(poly2): # 如果兩四邊形不相交iou = 0else:try:inter_area = poly1.intersection(poly2).area # 相交面積print(inter_area)union_area = MultiPoint(union_poly).convex_hull.areaprint(union_area)if union_area == 0:iou = 0# iou = float(inter_area) / (union_area-inter_area) #錯了iou = float(inter_area) / union_areaexcept shapely.geos.TopologicalError:print('shapely.geos.TopologicalError occured, iou set to 0')iou = 0print('line1_box:', line1_box)print('iou:', iou)?
?
總結
以上是生活随笔為你收集整理的正常矩形计算IOU与与NMS,多边形计算IOU的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: duilib中的添加自定义控件
- 下一篇: BoW(词袋Bag of words)