Comment détecter des objets distincts lorsque leurs bords se touchent?

21

J'ai besoin de trouver tous les contours dans une image récupérée de la caméra. Donc, j'utilise d'abord le détecteur de bord rusé pour trouver les bords, puis trouver les contours. Assez simple.

Cependant, mes contours sont «fusionnés». Par exemple, dans l'image ci-dessous, j'ai clairement 4 objets différents. Les bords se touchent légèrement à certains points, donc j'obtiens un gros contour au lieu de quatre séparés. J'ai essayé de changer autour des seuils, de l'érosion, des opérations de morphologie et des choses similaires, mais les bords restent légèrement en contact. Quelqu'un a-t-il des suggestions sur la façon d'obtenir des contours séparés dans des images similaires à celle ci-dessous? (L'image ci-dessous n'est évidemment qu'un exemple, mes images réelles sont beaucoup plus complexes, mais ont le même problème de base).

entrez la description de l'image ici

Lorem Ipsum
la source
La segmentation des bassins versants peut fonctionner.
sm176357
Donc, vous devriez également considérer les cas où le contact est une ligne et pas seulement un point aussi (touchant mais ne se chevauchant pas)
Shravya Boggarapu

Réponses:

11

Détection de différents composants:

Si vous essayez de détecter les différents composants, il existe probablement d'autres approches pour les faire que la détection des contours. Voici un exemple dans Mathematica. Une érosion suivie d'une dilatation est utilisée pour combler l'écart dans le deuxième composant avant la détection (si vous ne le faites pas, il ne le détectera pas).

img = Binarize@Import["http://i.stack.imgur.com/yqDyu.png"];
Colorize[MorphologicalComponents[Dilation[Erosion[img,1],1]]]

La figure de gauche ci-dessous montre une détection d'objet imparfaite (sans combler l'écart) et à droite, la détection correcte (en exécutant le code ci-dessus).

entrez la description de l'image ici entrez la description de l'image ici

Détection des différents contours:

Cependant, si vous souhaitez en effet ne séparer que les contours, voici un exemple. L'érosion et la dilatation sont effectuées comme précédemment pour combler l'écart et l'image résultante est passée à travers un détecteur de bord Canny. J'ai explicité les options par défaut, afin que vous puissiez voir ce qui est utilisé.

img2 = EdgeDetect[Dilation[Erosion[img, 1], 1], Method -> "Canny"]

Cela vous donnera à la fois le bord intérieur et extérieur (voir la figure à gauche ci-dessous), car la largeur de pixel est supérieure à 1 tout autour. Je n'ai pas eu beaucoup de chance pour essayer de l'amincir, car les performances se dégradent (peuvent être différentes pour vos autres images). Les contours intérieurs sont ceux que vous voulez, et le contour extérieur n'est que le contour combiné des 4 composants. Maintenant, tout ce que nous devons faire est de laisser tomber le plus extérieur avec:

SelectComponents[img2, "EnclosingComponentCount", # > 0 &]

ce qui vous donne juste les contours intérieurs (voir en bas à droite). En d'autres termes, il ne sélectionne que les contours qui sont entourés par au moins un autre contour, ce qui disqualifie automatiquement le plus externe. Je ne connais pas l'équivalent de ces commandes / opérations dans openCV.

entrez la description de l'image ici entrez la description de l'image ici

Notez que les ruptures apparentes dans la figure sont dues à l'enregistrement en jpeg dans une taille plus petite. Cela ne ressemble pas à ça sur mon écran.

Lorem Ipsum
la source
2

Essayez de prétraiter vos images avec un filtre morphologique comme l' érosion . Cela permettra de séparer les contours touchants. Après avoir détecté vos contours, vous pouvez appliquer une opération de dilatation pour compléter les réseaux.


la source
J'ai essayé, mais les résultats n'ont montré aucune amélioration.
1
Pouvez-vous montrer une image d'exemple réel?
2

Ce n'est pas une réponse à votre question, mais l'analyse des contours est sujette aux erreurs. Vous ne pouvez pas y faire grand-chose et cela ne fonctionne que sur des scénarios très simples.

Si vous avez du mal à l'utiliser, vous devez rechercher un algorithme complètement différent. Il existe des moyens plus complexes et plus robustes de résoudre les choses, mais cela dépend de ce que vous voulez réaliser (détection d'objet, suivi, etc ...)


la source
Merci. Mon programme est utilisé pour la détection des mains, donc je pense que ce serait très similaire à la détection d'objets. Avez-vous suggéré des algorithmes plus complexes et plus robustes? Les fonctionnalités Haar, SURF et les algorithmes d'apprentissage machine similaires ne sont pas quelque chose que je peux faire.
Avez-vous regardé ces ressources? paginas.fe.up.pt/~hgc2011 Ce sont principalement des bases de données / résultats, mais j'espère que vous pourrez trouver de bons articles ici.
0

Les contours ne sont pas nécessairement ouverts, sachez que vous les avez utilisés pour les détecter. Les problèmes avec Canny étaient déjà discutés ici . La discussion sur canny vous donne l'idée de base qu'il y a encore des opérations comme la fermeture et la dilatation qui sont nécessaires en plus de canny pour évaluer les contours fermés.

Cela dépend aussi si nous recherchons des contours ou des segmentations (Canny contre des méthodes comme Graphcuts ). Je suppose donc que la recherche d'une solution robuste dépend de votre application finale.

beedot
la source