web-dev-qa-db-fra.com

Vous utilisez la hiérarchie dans findContours () dans OpenCV?

Pour trouver des contours, j'ai utilisé l'argument CV_RETR_CCOMP. Ceci est censé créer une hiérarchie à deux niveaux - le premier niveau est pour les contours extérieurs, le deuxième niveau est pour les limites des trous. Cependant, je n'ai jamais utilisé de hiérarchie auparavant, je ne suis donc pas familier avec cela.

Quelqu'un pourrait-il m'informer sur la façon d'accéder aux limites des trous uniquement? Je veux ignorer les contours extérieurs et ne dessiner que les limites des trous. Des exemples de code seront appréciés. J'utilise l'interface C++ et non le C, donc veuillez ne pas suggérer de fonctions C (c'est-à-dire utiliser findContours () au lieu de cvFindContours ()).

32
fdh

La hiérarchie renvoyée par findContours a la forme suivante: hierarchy[idx][{0,1,2,3}]={next contour (same level), previous contour (same level), child contour, parent contour}

CV_RETR_CCOMP, renvoie une hiérarchie de contours extérieurs et de trous. Cela signifie que les éléments 2 et 3 de hierarchy[idx] ont au plus un de ces nombres différent de -1: autrement dit, chaque élément n'a ni parent ni enfant, ou un parent mais pas d'enfant, ou un enfant mais pas de parent.

Un élément avec un parent mais sans enfant serait la limite d'un trou.

Cela signifie que vous passez essentiellement par hierarchy[idx] et dessinez n'importe quoi avec hierarchy[idx][3]>-1.

Quelque chose comme (fonctionne en Python, mais n'a pas testé le C++. L'idée est très bien.):

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 );
        }
    }
}
41
mathematical.coffee

AFAIK lors de l'utilisation de CV_RETR_CCOMP, tous les trous sont au même niveau.

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.
4
Shmuel Fine