2017-09-17 179 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")