OpenCV - approxPolyDP de bord des cartes (pas de contours)
J'ai appliqué avec succès la méthode de cv::approxPolyDP sur les contours (cv::findContours), dans le but de représenter un contour à l'aide d'un simple polygone et implicitement certains de débruitage.
Je voudrais faire la même chose sur un bord de la carte acquis à partir d'une RGBD de la caméra (qui est en général très bruyant), mais avec pas beaucoup de succès jusqu'à maintenant et je ne trouve pas relative des exemples en ligne. La raison que j'ai besoin de ceci, est que par le biais d'un bord de la carte, on peut aussi utiliser les bords entre les doigts, sur les bords créé par occlusion du doigt ou de bords dans la paume de la main.
Cette méthode est-elle applicable à l'avantage concurrentiel général des cartes, autres que les contours?
Quelqu'un pourrait m'identifier à un exemple?
Quelques images en pièce jointe:
Exemple de réussite pour les contours:
Cas problématique de bord des cartes:
Plus probablement je dessine des choses dans le mauvais sens, mais de tracer les pixels retourné par la méthode montre que, probablement, de grandes zones ne sont pas représentés dans le résultat final (et ce n'est pas beaucoup de changement en fonction de l'epsilon-paramètre).
J'attache aussi une image de profondeur, semblables à celles que j'utilise dans le expérimentales pipeline décrite ci-dessus. Cette image de profondeur n'a pas été acquise par la profondeur de la caméra, mais a été synthétiquement générés par la lecture de la profondeur de la mémoire tampon de la carte graphique, en utilisant OpenGL.
Juste pour la référence, c'est à la limite de la carte de la profondeur de l'image acquise directement à partir de la profondeur de l'appareil (à l'aide de l'image brute, sans lissage, etc appliquée)
(à la main comme viewd à partir d'une profondeur de caméra, paume tournée vers le haut, les doigts "clôture" en direction de la palmeraie)
cv::findContours
. Pourriez-vous poster une des images originales de la RGBD de la caméra? (Peut-être la profondeur de l'image). Si le débruitage est nécessaire, elle doit être appliquée avant de contour/edge trouver.Salut rwong, dans ce cas, je n'utilise pas de cv::findContours, j'applique Savant Détection de Bord sur le bord de l'image. Pour le moment je n'ai pas denoise le bord de l'image à l'avance, comme je l'ai d'abord voulu voir la qualité des données réelles acquises, mais vous avez raison, on devrait également réduire le bruit un peu avant la limite de détection. Je remarque cependant que, dans une première étape, j'utilise de façon synthétique les données générées (tampon de profondeur de OpenGL), donc pas de débruitage est nécessaire dans les exemples que j'ai posté. Je vais modifier la question pour ajouter le synthétique de la profondeur de l'image.
Pour les Futés de Détection de contours, en abaissant le seuil le plus bas (tout en gardant le seuil plus élevé même) se traduira par plus de pixels du contour étant marqué, et donc de réduire le risque de lacunes en bord de chaînes. Je n'ai pas utilisé
approxPolyDP
avant, donc je ne pouvais pas faire de commentaires. La leçon est que si il y a une imperfection en une seule étape, il est généralement difficile de fixer dans les étapes suivantes.C'est vrai, mais les images montrent que le savant détection de bord est suffisant, en fournissant un sens au bord de la carte (en plus, en abaissant le seuil donne plus intérieure-bords, aucune influence significative sur les bords). Donc, il n'y a pas d'artefact, à ce stade, je suppose, c'est soit que j'utilise approxPpolyDP dans un mauvais sens, ou il ne peut pas gérer les non-fermé-cartes de contours (qui je pense n'est pas le cas, en se fondant également sur les paramètres d'entrée de la méthode).
OriginalL'auteur dim_tz | 2014-03-02
Vous devez vous connecter pour publier un commentaire.
Votre problème avec
approxPolyDP
est due à la mise en forme de l'entrée enapproxPolyDP
.Explication
approxPolyDP
attend son entrée à être un vecteur dePoint
s. Ces points définissent une courbe polygonale qui seront traitées par leapproxPolyDP
. La courbe peut être ouvert ou fermé, qui peut être contrôlée par un drapeau.L'ordre des points dans la liste est importante. Tout comme on trace un polygone à la main, chaque point dans le vecteur doit être le prochain sommet du polygone, dans le sens horaire ou dans le sens antihoraire.
Si la liste de points est stocké dans le raster de commande (triés par Y et X), alors la
point[k]
etpoint[k+1]
n'appartiennent pas nécessairement à la même courbe. C'est la cause du problème.Ce problème est expliqué avec des illustrations en OpenCV - Comment extraire des bords résultat du formulaire de Savant Fonction? . Citation de Mikhail: "le Savant n'a pas connecter les pixels dans des chaînes ou des segments."
Illustration de la "trame de commande" qui est généré par
Canny
.Illustration de "le contour de l'ordre" qui est attendue par
approxPolyDP
Ce qui est nécessaire
Ce que vous avez besoin est une liste de chaînes de pixels de contour". Chaque chaîne doit contenir des pixels de contour qui sont adjacents les uns aux autres, comme une personne à tracer un contour de l'objet par un crayon, sans la pointe du crayon, en laissant le papier.
Ce n'est pas ce qui est retourné de bord des méthodes de détection, tels que
Canny
. La poursuite du traitement est nécessaire pour convertir un bord de la carte dans les chaînes adjacentes (continue) des pixels de contour.Solutions proposées
(1) Utiliser les binaires
threshold
au lieu de la détection des bords de l'entrée defindContours
Ce serait applicable s'il existe une valeur seuil qui sépare la main de l'arrière-plan, et que cette valeur fonctionne pour l'ensemble de la main (et non seulement la partie de la main).
(2) Analyser le bord de la carte, et de construire la liste des pixels adjacents en examinant les voisins de chaque bord pixel.
Ceci est similaire à la connectés-les composants de l'algorithme, sauf qu'au lieu de trouver un blob (où vous avez seulement besoin de connaître chaque pixel de l'adhésion), vous essayez de trouver des chaînes de pixels tels que vous pouvez dire au précédent et au suivant pixels des bords le long de la chaîne.
(3) Utiliser un autre bord de l'algorithme de détection, tels que Edge Dessin.
Détails peuvent être trouvés à http://ceng.anadolu.edu.tr/cv/EdgeDrawing/
Malheureusement, ce n'est pas out-of-the-box à partir de OpenCV, de sorte que vous pouvez être amené à rechercher une mise en œuvre ailleurs.
Exemple de code pour l'option #1.
pour un rapide (hacky!) test est l'utilisation habile détecteur de bord, de l'inverser, puis utilisez le seuil de la méthode et de l'alimentation avec le résultat de la findcontours méthode. Il va y avoir le problème d'un double contour autour de chaque bord, ce qui, selon votre demande, peut être ou ne pas être ok. En fin de compte j'ai décidé de ne pas utiliser tout de lissage/filtrage ou de rapprochement des contours puisqu'il n'aide pas pour le projet en cours, mais la réponse est exceptionnel et très analytique. Pour référence future, les personnes avec un problème similaire devrait considérer que la meilleure solution soit de la deuxième ou de la troisième option.
Que le turc site de l'université est un pain PITA - le CompVis de recherche de l'équipe du sous-site (le /cv/ bits de l'URL), a donné un 503 pendant des heures. Je n'ai pas trop envie de payer 35 $pour une copie du document d'Elsevier, soit... il y a un résumé de papier ici -> researchgate.net/publication/... qui semble prometteur: j'ai ~2 millions d'images pour lesquelles je suis en train de mettre en œuvre certaines de détection de fonctionnalité, de sorte que quelques msec enregistrés ici et là ajouter jusqu'à des temps (je croise les doigts, encore plus si j'utilise le Gpu)
OriginalL'auteur rwong