2011-12-14 14 views
7

Ho due contorni e voglio verificare la relazione tra loro (se uno di essi è annidato). Normalmente, vorrei usare la funzione findContours con la modalità di recupero CV_RETR_TREE. Tuttavia, ho ottenuto i contorni da una fonte diversa (usando il metodo MSER). In realtà non solo ho i contorni, ma anche la maschera della regione se questo aiuta. Ad esempio, consente di dire che voglio per segmentare la lettera 'O', quindi vorrei avere le seguenti maschere o contorni:Come verificare se un contorno è annidato/incorporato in opencv

1)

0 0 0 0 0 0 
0 1 1 1 1 0 
0 1 0 0 1 0 
0 1 0 0 1 0 
0 1 1 1 1 0 
0 0 0 0 0 0 

2)

0 0 0 0 0 0 
0 0 0 0 0 0 
0 0 1 1 0 0 
0 0 1 1 0 0 
0 0 0 0 0 0 
0 0 0 0 0 0 

Come posso verificare facilmente che il secondo si trovi all'interno del primo contorno? Ho pensato di verificare la relazione tra i riquadri di delimitazione, ma questo non copre tutti i casi possibili.

risposta

6

Utilizzare cv::pointPolygonTest(InputArray contour, Point2f pt, bool measureDist) per sapere se un punto da un contorno si trova all'interno dell'altro.

devi verificare casi di confine (il primo punto selezionato è comune ai due poligoni, ecc)

if(pointPolygonTest(contour, pointFromOtherContour, false) > 0) 
{ 
    // it is inside 
} 

La funzione determina se il punto è all'interno di un contorno, fuori, o si trova su un bordo (o coincide con un vertice). Restituisce il valore positivo (interno), negativo (esterno) o zero (su un bordo), in modo corrispondente.

Quando measureDist=false, il valore restituito è +1, -1 e 0, rispettivamente. Altrimenti, il valore di ritorno è una distanza segnata tra il punto e il bordo del contorno più vicino.

1

Se si sa che i contorni sono chiusi (in senso 4), è possibile utilizzare probabilmente il test raggio infinito, che è più comunemente utilizzato per verificare se i punti si trovano all'interno di poligoni chiusi. (Anche supponendo che i contorni non si incrocino, che presumibilmente non possono.)

Prendere qualsiasi punto sul profilo candidato, e procedere da lì a 'infinito' in qualsiasi direzione (selezionare un asse allineato uno, per facilità di implementazione): se si arriva fino al bordo dell'immagine e si attraversa il contorno esterno un numero dispari di volte, il contorno che si è avviato si trova all'interno di quel contorno.

il contorno esterno 'traversata' è in realtà un po 'complicato, per esempio:

. 1 1 1 1 1 1 1 
    . 1 . . X X X 1 
    . 1 . . X . X 1 
<-.-1-1-.-X X X 1 : here a naiive implementation counts two crossings 
    . . 1 1 1 1 1 1 

Quindi, per testare se un raggio è 'incrocio' un contorno in un punto si ha realmente bisogno di prendere in considerazione i punti di 3x3 vicini. Credo che ci si ritroverà con una serie di casi che sembrano qualcosa di simile:

. . . 
<-1-1 1 // not crossing 
    . . . 

    1 . 1 
<-1-1 1 // not crossing 
    . . . 

    . . 1 
<-1-1 1 // crossing 
    . . . 

    1 . . 
<-1-1 1 // crossing 
    . . . 

Io non sono sicuro al 100% che è possibile costruire una prova consistente per attraversamenti un contorno 4 collegato sulla base di 3x3 quartieri, ma sembra probabile che lo sia.

Tutto ciò si basa sul contorno esterno che viene chiuso, ovviamente.

Problemi correlati