2017-09-17 1 views
3

Ich habe mehrere überlappende Bounding-Boxen, die ein einzelnes Objekt umfassen, jedoch überlappen sie sich an einigen Stellen minimal. Zusammengenommen umfassen sie das gesamte Objekt, aber die Funktion groupRectangles von openCV gibt keine Box zurück, die das Objekt umfasst. Die Begrenzungsboxen Ich habe in blau dargestellt, und Begrenzungskästen Ich möchte hier zurückkehren gezeigt in rotSuche nach der Vereinigung mehrerer überlappender Rechtecke - OpenCV python

Ich möchte die Vereinigung nur die überlappenden Rechtecke bekommen, aber bin nicht sicher, wie man Iteriere die Liste, ohne jedes Rechteck zu kombinieren. Ich habe unten gezeigte Vereinigungs- und Schnittpunktfunktionen und eine Liste der Rechtecke, die durch (x y w h) dargestellt werden, wobei x und y die Koordinaten der oberen linken Ecke des Rechtecks ​​sind.

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) 

Meine Funktion zum Kombinieren ist zur Zeit wie folgt:

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") 

Dies wird es den größten Teil der Art und Weise, wie hier gezeigt

gibt es noch ein paar verschachtelte Begrenzungs Boxen, von denen ich nicht weiß, wie ich weitermachen soll.

+0

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

+0

ist 'boxes' nur numpy Array? 'print (type (boxes))' – salparadise

+0

@Zindarod, ich habe versucht, das vorher zu verwenden, aber leider ergibt es ein ähnliches Ergebnis wie groupRectangles, da es eine kleine 'durchschnittliche' Bounding Box zurückgibt, die nicht mein gesamtes Objekt abdeckt – mechaddict

Antwort

1

Ich habe nicht mit OpenCV gearbeitet, so dass das Objekt mehr Mangeln müssen, aber vielleicht itertools.combinations verwendet die combine_boxes Funktion einfacher zu machen:

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 (Sie tatsächlich zip stattdessen benötigen)

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

alles ist gleich.

+0

Ich war nicht vertraut mit der 'itertools.combinations() 'Funktion, aber das sieht tatsächlich viel schöner aus als das, was ich tat. Ich werde versuchen, das zu implementieren, weil es viel besser/schneller scheint. – mechaddict

+0

@Mechaddict hinzugefügt Zip nachdem Sie erneut auf Ihr Problem. – salparadise

0

Es ist schrecklich janky, aber nach ein bisschen finagling habe ich verwalten, um die Ergebnisse bekomme ich

wollte

ich meine combine_boxes Funktion unten im Fall enthalten sind, jemand ein ähnliches Problem hat.

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") 
Verwandte Themen