détection de formes-approximation de contour avec OpenCV
j'écris une petite application pour les détections de forme. Ce que je dois faire en premier lieu, c'est trouver la forme la plus significative sur une image. Je suis parti d'un prétraitement comprenant la conversion d'image en échelle de gris, le battage et la détection de bord. Image avant et après ces opérations est présenté ci-dessous
Avant
après
comme vous pouvez le voir la forme principale est visible (cependant, il est un peu dispersée) et il y a aussi quelques bruits (petits arbres, etc). Ce que je dois faire est d'extraire d'une façon ou d'une autre seulement la forme la plus significative (la plus grande) - dans ce cas, c'est une tour. Ce que je voulais faire, c'est utiliser la fonction de recherche de contour dans opencv et puis d'une façon ou d'une autre aproximate trouvé des contours avec polygon. Puis je calculerais (en quelque sorte) la surface de countours et choisirais seulement le plus grand. Jusqu'à présent j'ai manié (seulement) pour trouver des contours en utilisant
cvFindContours(crated,g_storage,&contours);
je sais qu'il y est un
cvApproxPoly
fonction, cependant je ne suis pas en mesure d'obtenir des informations utiles pour le résultat de cette fonction. Quelqu'un pourrait-il me dire s'il est possible de calculer la surface de contour ou de rapprocher le contour du polygone? Peut-être avez-vous une meilleure idée pour extraire seulement la forme la plus significative ?
4 réponses
vous n'avez pas à faire de détection de bord ici. Juste le seuil à une image binaire et puis trouver des blobs (cvFindContours) sur cela. Vous pouvez utiliser cvContourArea sur chaque CvSeq retourné pour trouver sa zone.
si vous avez toujours un arrière-plan contrôlé, j'opterais pour ces étapes (comme suggéré aussi par @damian):
- Binarisation, c'est-à-dire la création d'une image telle que l'arrière-plan = 0 et les régions d'objet = 1 (ou 255). Après cela, vous aurez plusieurs zones blanches sur votre image. Il y a plusieurs méthodes pour le faire, mais si votre arrière-plan est contrôlé, vous pouvez utiliser un seuil fixe. Notez qu'ici vous avez enlevé le bruit à l'intérieur des objets. Dans le binaire image, vous pouvez toujours utiliser morphologiques de l'ouverture/fermeture, afin de lisser les objets
- Utiliser cvFindContours trouver tous les objets: il devrait être plus facile maintenant.
- remplissez les contours plus petits avec la couleur de fond en utilisant cvFloodFill.
votre problème principal est que le contour de la tour est dispersé. Il sera difficile de recréer le contour entier de ces petits morceaux. Optimisez votre Phase de détection de bord (essayez cvAdaptiveThreshold
), ou utiliser une approche différente (peut-être quelque chose comme segmentation de l'objet)
Après vous avez votre contour en un seul morceau, vous pouvez vérifier son domaine comme ceci:
CvSeq* convex_hull=cvConvexHull2( contour, storage, CV_CLOCKWISE, 2 );
CvSeq* quad=cvApproxPoly(convex_hull, sizeof(CvContour), storage, CV_POLY_APPROX_DP, cvContourPerimeter(contour)*0.02, 0);
float size=fabs(cvContourArea( quad,CV_WHOLE_SEQ,0 ));
vous devrez ajuster les paramètres. Il a été utilisé pour détecter les rectangles.
vous pouvez utiliser des opérations morphologiques pour supprimer votre "bruit de contour" (dilatation dans votre cas). Mais vous devez vous rappeler que la facilité d'utilisation des opérations morphologiques dépend de la tâche actuelle. Par exemple, si vous avez deux objets placés l'un près de l'autre, dilation peut faire un objet à partir de ceux-ci.