日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Python合并重疊矩形框_python

作者:songxf ? 更新時間: 2022-05-19 編程語言

需求:

  • NMS中的IOU相關,是選擇一個最大或者可信度最高的框框保留。
  • 而我們現在試需要將重疊框框合并為一個大的框框,所以不能直接用上面的。
  • 并且OpenCVgroupRectangles在Python中我實在用不懂,而且它會把不重疊的框直接刪了。。

原理:

  • 循環+遞歸,依次判斷兩個框是否有重疊。

效果:

參考代碼:

import cv2
import numpy as np


def checkOverlap(boxa, boxb):
? ? x1, y1, w1, h1 = boxa
? ? x2, y2, w2, h2 = boxb
? ? if (x1 > x2 + w2):
? ? ? ? return 0
? ? if (y1 > y2 + h2):
? ? ? ? return 0
? ? if (x1 + w1 < x2):
? ? ? ? return 0
? ? if (y1 + h1 < y2):
? ? ? ? return 0
? ? colInt = abs(min(x1 + w1, x2 + w2) - max(x1, x2))
? ? rowInt = abs(min(y1 + h1, y2 + h2) - max(y1, y2))
? ? overlap_area = colInt * rowInt
? ? area1 = w1 * h1
? ? area2 = w2 * h2
? ? return overlap_area / (area1 + area2 - overlap_area)

def unionBox(a, b):
? ? x = min(a[0], b[0])
? ? y = min(a[1], b[1])
? ? w = max(a[0] + a[2], b[0] + b[2]) - x
? ? h = max(a[1] + a[3], b[1] + b[3]) - y
? ? return [x, y, w, h]

def intersectionBox(a, b):
? ? x = max(a[0], b[0])
? ? y = max(a[1], b[1])
? ? w = min(a[0] + a[2], b[0] + b[2]) - x
? ? h = min(a[1] + a[3], b[1] + b[3]) - y
? ? if w < 0 or h < 0:
? ? ? ? return ()
? ? return [x, y, w, h]

def rectMerge_sxf(rects: []):
? ? # rects => [[x1, y1, w1, h1], [x2, y2, w2, h2], ...]
? ? '''
? ? 當通過connectedComponentsWithStats找到rects坐標時,
? ? 注意前2個坐標是表示整個圖的,需要去除,不然就只有一個大框,
? ? 在執行此函數前,可執行類似下面的操作。
? ? rectList = sorted(rectList)[2:]
? ? '''
? ? rectList = rects.copy()
? ? rectList.sort()
? ? new_array = []
? ? complete = 1
? ? # 要用while,不能forEach,因爲rectList內容會變
? ? i = 0
? ? while i < len(rectList):
? ? ? ? # 選後面的即可,前面的已經判斷過了,不需要重復操作
? ? ? ? j = i + 1
? ? ? ? succees_once = 0
? ? ? ? while j < len(rectList):
? ? ? ? ? ? boxa = rectList[i]
? ? ? ? ? ? boxb = rectList[j]
? ? ? ? ? ? # 判斷是否有重疊,注意只針對水平+垂直情況,有角度旋轉的不行
? ? ? ? ? ? if checkOverlap(boxa, boxb): ?# intersectionBox(boxa, boxb)
? ? ? ? ? ? ? ? complete = 0
? ? ? ? ? ? ? ? # 將合並後的矩陣加入候選區
? ? ? ? ? ? ? ? new_array.append(unionBox(boxa, boxb))
? ? ? ? ? ? ? ? succees_once = 1
? ? ? ? ? ? ? ? # 從原列表中刪除,因爲這兩個已經合並了,不刪除會導致重復計算
? ? ? ? ? ? ? ? rectList.remove(boxa)
? ? ? ? ? ? ? ? rectList.remove(boxb)
? ? ? ? ? ? ? ? break
? ? ? ? ? ? j += 1
? ? ? ? if succees_once:
? ? ? ? ? ? # 成功合並了一次,此時i不需要+1,因爲上面進行了remove(boxb)操作
? ? ? ? ? ? continue
? ? ? ? i += 1
? ? # 剩餘項是不重疊的,直接加進來即可
? ? new_array.extend(rectList)

? ? # 0: 可能還有未合並的,遞歸調用;
? ? # 1: 本次沒有合並項,說明全部是分開的,可以結束退出
? ? if complete == 0:
? ? ? ? complete, new_array = rectMerge_sxf(new_array)
? ? return complete, new_array


box = [[20, 20, 20, 20], [100, 100, 100, 100], [60, 60, 50, 50], [50, 50, 50, 50]]
_, res = rectMerge_sxf(box)
print(res)
print(box)

img = np.ones([256, 256, 3], np.uint8)
for x,y,w,h in box:
? ? img = cv2.rectangle(img, (x,y), (x+w,y+h), (0, 255, 0), 2)
cv2.imshow('origin', img)

img = np.ones([256, 256, 3], np.uint8)
for x,y,w,h in res:
? ? img = cv2.rectangle(img, (x,y), (x+w,y+h), (0, 0, 255), 2)
cv2.imshow('after', img)

cv2.waitKey(0)

原文鏈接:http://xfxuezhang.cn/index.php/archives/231/

欄目分類
最近更新