7
votes

Définir si un contour est fermé ou non

J'ai besoin d'un moyen de définir si un contour représente une ligne ou une forme fermée. En Java, j'ai un objet la forme qui contient tous les points qui le définissent à nouveau comme des objets distincts. L'objet point représente les coordonnées du point. J'ai essayé d'analyser les formes avec une récursion mais pour des formes plus grandes, plus de 150 points, la performance est très médiocre. J'attache une image des formes que je veux analyser pour mieux comprendre la question.

Je pose une image pour une meilleure visualisation du problème.

Entrez la description de l'image ici

Cela vient de montrer toutes les formes que j'ai eues. Je veux afficher uniquement les deux fermés.

Merci d'avance. Vassil Kossev


6 commentaires

Je pense que vous voulez marquer la question avec "algorithme"?


Merci. Je savais que j'ai oublié quelque chose.


Les points sont-ils enroulé dans une bague ou juste la liste dans un ordre arbitraire?


Devez-vous aussi séparer les contours fermés de ceux ouverts? Ou vous avez un algorithme pour les séparer et je veux simplement déterminer si un contour donné est fermé ou ouvert?


Je veux déterminer si un contour donné de l'image est fermé ou ouvert. Si c'est fermé, je l'affiche s'il est ouvert, je m'en fous.


Tous les "contours" sont fermés, du moins avec l'utilisation de "contour" avec lequel je suis familier: la courbe de la valeur constante d'une fonction continue. Par exemple, cette image ressemble à un raster SIG d'élévation qui a traversé un très mauvais algorithme de traçage contour.


3 Réponses :


1
votes

Si les points sont stockés dans l'ordre, vous pourrez peut-être comparer les premier et dernier points. S'ils sont égaux spatialement, le contour est fermé.


2 commentaires

Malheureusement, les points ne sont pas triés. Mais s'il y a un moyen de les trier, cela sera utile. Que peuvent être les critères de tri des coordonnées?


Vous voulez que les coordonnées sont trichées dans une bague. Webmonster a fourni un lien vers un couple d'algorithmes de traçage de contour - l'un de ceux-ci fonctionnera bien.



8
votes

première idée: Utilisez un Algorithme de traçage de contour à Obtenez un contour commandé. Si votre contour est fermé, vous revenez au premier point finalement.

Deuxième idée: Utilisez un Algorithme de remplissage d'inondation : Si vous sortez de la boîte de sélection de Votre objet est ouvert, sinon il est fermé.

Troisième idée: Utilisez la morphologie. Enlever les pixels isolés. Trouvez tous les points finaux et tous les succursales. Supprimer tous les succursales. Les composants connectés sans points d'extrémité sont des contours fermés ("cercles"), les composants connectés avec deux extrémités sont des contours ouverts ("lignes"). Composants connectés à ré-projet sans points de terminaison à l'image d'origine et ne conservent que des composants connectés qui ont une partie commune avec eux. Je pense que cela pourrait être mis en œuvre en temps réel et le plus facile à mettre en œuvre.


1 commentaires

Quatrième idée (supprimé parce que je ne suis pas sûr si cela fonctionne): Choisissez un point qui est sûrement à l'intérieur de votre objet (par exemple, point de masse pour objets convexes) et dessinez des lignes radiales avec angle de petites étapes raisonnablement petites. Si le nombre d'intersections du contour de votre objet et des lignes est toujours étrange - vous avez un contour fermé. Sinon, votre objet est ouvert.



2
votes

Si vous avez des lignes de contour de 1 pixel largeur, alors vous peut compter le nombre de voisins pour chaque point * . Si chaque point d'un contour donné a 2 voisins, le contour est fermé . S'il y a 2 points avec seulement 1 voisin, alors le contour est ouvert .

Si vos contours sont plus épais, vous pouvez appliquer une algorithme skeletonisation pour les faire exactement 1 pixel mince. Un cas intéressant est que lorsque vous avez branches latérales sur un contour, mais dans ce cas, il doit y avoir des points de ramification avec 3 voisins, des situations similaires peuvent être manipulées facilement.

* Compter les voisins est facile: utilisez l'image d'origine! Choisissez un point du contour au hasard, vérifiez les 8 pixels voisins et comptez ceux qui font partie du contour. Ensuite, répétez la vérification de la voisine pour ceux-ci, et ainsi de suite, jusqu'à ce que tous les pixels du contour aient été vérifiés.


3 commentaires

Malheureusement, selon la manière dont vous comptez les voisins, vous pouvez avoir plusieurs points avec un seul voisin et avoir un contour fermé, de sorte que la première méthode que vous suggère peut produire de faux négatifs.


C'est pourquoi j'ai écrit sur la squelette et la manipulation des branches latérales. Il y a des années, j'ai appliqué cette approche dans un programme qui a extrait les coordonnées des points de graphiques numérisés (chiffres d'articles scientifiques). J'ai eu des lignes épaisses courbées et bruyantes, alors je devais les lisser d'abord un peu. Ensuite, j'ai appliqué mon algorithme de squelette et, après cela, j'ai enlevé les branches latérales. J'ai traité de la même manière non seulement des lignes de graphique, mais les axes du graphique également, donc comme une dernière étape, le programme pourrait calibrer les points des lignes de graphique et les enregistrer directement à Matlab et Excel :)


Merci beaucoup pour cette idée. J'ai décidé d'utiliser celui-ci parce que c'est le plus simple et le plus simple et c'est ce dont j'avais besoin.