2017-09-17 1 views
3

J'ai plusieurs zones de délimitation superposées qui englobent un seul objet, mais elles se chevauchent de façon minimale à certains endroits. Pris dans leur ensemble, ils englobent l'objet entier, mais la fonction groupRectangles d'openCV ne renvoie pas de boîte englobant l'objet. Les boîtes englobantes I ont sont en bleu, et des boîtes englobantes je voudrais revenir sont en rouge iciRecherche de l'union de plusieurs rectangles superposés - OpenCV python

Je voudrais obtenir l'union des seuls les rectangles qui se chevauchent, mais je suis incertain sur la façon de parcourez la liste sans combiner chaque rectangle. J'ai les fonctions d'union et d'intersection illustrées ci-dessous, et une liste des rectangles représentés par (x y w h), où x et y sont les coordonnées du coin supérieur gauche de la boîte.

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) 

Ma fonction pour combiner est actuellement comme suit:

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

Cela devient la plupart du chemin, comme indiqué ici

il y a encore quelques englobante imbriquées boîtes que je ne suis pas sûr de savoir comment continuer itération à travers.

+0

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

+0

est 'boxes' juste un tableau numpy? 'print (type (boîtes))' – salparadise

+0

@Zindarod, j'essayais de l'utiliser précédemment, mais malheureusement, il donne un résultat similaire à groupRectangles, en ce sens qu'il retourne une petite boîte englobante 'moyenne' qui ne couvre pas tout mon objet – mechaddict

Répondre

1

Je n'ai pas travaillé avec OpenCV, de sorte que l'objet peut avoir besoin de plus mutiler, mais peut-être utiliser itertools.combinations pour rendre la fonction combine_boxes plus simple:

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 (vous pouvez réellement besoin zip place)

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

tout est pareil.

+0

Je ne connaissais pas le 'itertools.combinations() 'Fonction, mais cela semble vraiment beaucoup plus agréable que ce que j'ai réellement fait. Je vais essayer de l'implémenter car il semble beaucoup plus propre/plus rapide. – mechaddict

+0

@mechaddict ajouté zip après avoir examiné votre problème à nouveau. – salparadise

0

Il est horriblement Janky, mais après un peu de finagling j'ai réussi à obtenir les résultats que je voulais

J'ai inclus ma fonction combine_boxes qui que ce soit dans le cas ci-dessous est d'avoir un problème similaire.

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