2017-09-17 178 views
3

我有幾個重疊的包圍單個對象的邊界框,但它們在一些地方重疊最小。整體而言,它們包含整個對象,但openCV的groupRectangles函數不返回包含該對象的框。邊界框我都顯示爲藍色,和邊框我想返回顯示爲紅色,這裏找到多個重疊矩形的聯合 - OpenCV蟒蛇

我想只得到重疊矩形的聯合,但我不確定如何迭代遍歷列表,而不用組合每個矩形。 我有如下所示的聯合函數和相交函數,以及由(x y w h)表示的矩形列表,其中x和y是框左上角的座標。

def union(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 intersection(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() # or (0,0,0,0) ? 
    return (x, y, w, h) 

我對合並功能目前如下:

def combine_boxes(boxes): 
    noIntersect = False 
    while noIntersect == False and len(boxes) > 1: 
     a = boxes[0] 
     print a 
     listBoxes = boxes[1:] 
     print listBoxes 
     index = 0 
     for b in listBoxes: 
      if intersection(a, b): 
       newBox = union(a,b) 
       listBoxes[index] = newBox 
       boxes = listBoxes 
       noIntersect = False 
       index = index + 1 
       break 
      noIntersect = True 
      index = index + 1 

    print boxes 
    return boxes.astype("int") 

這得到大多數的方式存在,因爲這裏

顯示仍有一些嵌套邊界我不確定如何繼續迭代。

+0

http://www.pyimagesearch.com/2014/11/17/non-maximum-suppression-object-detection-python – zindarod

+0

是'boxes'只是numpy的陣列? 'print(type(boxes))' – salparadise

+0

@Zindarod,我之前嘗試過使用它,但不幸的是它給出了一個類似於groupRectangles的結果,因爲它返回一個小的「平均」邊界框,它不覆蓋我的整個對象 – mechaddict

回答

1

我還沒有跟OpenCV的工作,所以對象可能需要更多的mangling,但也許使用itertools.combinations使combine_boxes功能簡單:

import itertools 
import numpy as np 
def combine_boxes(boxes): 
    new_array = [] 
    for boxa, boxb in itertools.combinations(boxes, 2): 
     if intersection(boxa, boxb): 
      new_array.append(union(boxa, boxb)) 
     else: 
      new_array.append(boxa) 
    return np.array(new_array).astype('int') 

EDIT(你實際上可能需要zip代替)

for boxa, boxb in zip(boxes, boxes[1:]) 

一切都是一樣的。

+0

我對itertools.combinations() '功能,但實際上看起來比我實際做得更好。我會嘗試實現,因爲它看起來更整潔/更快。 – mechaddict

+0

@mechaddict在再次查看您的問題後添加了zip。 – salparadise

0

這是可怕的janky,但有點finagling後,我還是設法得到我想要

我已經包括了我的combine_boxes功能在以下情況下,任何人有類似的問題的結果。

def combine_boxes(boxes): 
    noIntersectLoop = False 
    noIntersectMain = False 
    posIndex = 0 
    # keep looping until we have completed a full pass over each rectangle 
    # and checked it does not overlap with any other rectangle 
    while noIntersectMain == False: 
     noIntersectMain = True 
     posIndex = 0 
     # start with the first rectangle in the list, once the first 
     # rectangle has been unioned with every other rectangle, 
     # repeat for the second until done 
     while posIndex < len(boxes): 
      noIntersectLoop = False 
      while noIntersectLoop == False and len(boxes) > 1: 
       a = boxes[posIndex] 
       listBoxes = np.delete(boxes, posIndex, 0) 
       index = 0 
       for b in listBoxes: 
        #if there is an intersection, the boxes overlap 
        if intersection(a, b): 
         newBox = union(a,b) 
         listBoxes[index] = newBox 
         boxes = listBoxes 
         noIntersectLoop = False 
         noIntersectMain = False 
         index = index + 1 
         break 
        noIntersectLoop = True 
        index = index + 1 
      posIndex = posIndex + 1 

    return boxes.astype("int")