2011-12-11 20 views
29

Al encontrar contornos, utilicé el argumento CV_RETR_CCOMP. Se supone que esto crea una jerarquía de dos niveles: el primer nivel es para contornos exteriores, el segundo nivel es para los límites de los agujeros. Sin embargo, nunca he usado una jerarquía antes, así que no estoy familiarizado con esto.¿Usar la jerarquía en findContours() en OpenCV?

¿Alguien podría indicarme cómo acceder a los límites de los agujeros solamente? Quiero ignorar los contornos exteriores y solo dibujar los límites del agujero. Los ejemplos de código serán apreciados. Estoy usando la interfaz C++, no la C, así que no sugiera funciones C (es decir, use findContours() en lugar de cvFindContours()).

+0

Ir entre la versión C++ y la versión C es trivial. FYI. –

Respuesta

36

La jerarquía devuelto por findContours tiene la siguiente forma: hierarchy[idx][{0,1,2,3}]={next contour (same level), previous contour (same level), child contour, parent contour}

CV_RETR_CCOMP, devuelve una jerarquía de contornos exteriores y agujeros. Esto significa que los elementos 2 y 3 de hierarchy[idx] tienen como máximo uno de estos no igual a -1: es decir, cada elemento no tiene padre o hijo, o un padre pero no hijo, o un hijo pero no padre.

Un elemento con un elemento primario pero sin elemento secundario sería un límite de un agujero.

Eso significa que básicamente vas a hierarchy[idx] y dibujas cualquier cosa con hierarchy[idx][3]>-1.

Algo así como (. Obras en Python, pero no se han puesto a prueba la idea de C++ está bien, aunque.):

findContours(image, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE); 

if (!contours.empty() && !hierarchy.empty()) { 

    // loop through the contours/hierarchy 
    for (int i=0; i<contours.size(); i++) { 

     // look for hierarchy[i][3]!=-1, ie hole boundaries 
     if (hierarchy[i][3] != -1) { 
      // random colour 
      Scalar colour((rand()&255), (rand()&255), (rand()&255)); 
      drawContours(outImage, contours, i, colour); 
     } 
    } 
} 
+1

@ Farhad, asegúrese de hacer algunas pruebas. La jerarquía puede no ser lo que esperas. Intenté esto con su imagen de http://stackoverflow.com/questions/8449378/finding-contours-in-opencv y el marco de la imagen era un elemento primario, el contorno exterior era un elemento secundario, y el contorno interior no era ninguno. – SSteve

+0

@Farhad Lo siento, quise decir que el marco de la imagen era un niño y el contorno exterior del círculo era uno de los padres. – SSteve

+0

Gracias, supongo que tendré que encontrar una forma de evitarlo. – fdh

3

yo sepa cuando se utiliza CV_RETR_CCOMP, todos los agujeros están en el mismo nivel.

int firstHoleIndex = hierarchy[0][2]; 
for (int i = firstHoleIndex; i >= 0 ; i = hierarchy[i][0]) 
// contours.at(i) is a hole. Do something with it.