J'ai des images binaires 160x120 telles que:
Je voudrais détecter les coins de ces taches blanches. Ils sont auparavant fermés par la morphologie mathématique donc il ne devrait pas y avoir de coins intérieurs. Dans ce cas spécifique, je voudrais 16 coins, comme:
Ma première tentative a été d'utiliser certaines fonctions OpenCV comme goodFeaturesToTrack ou FAST mais elles sont particulièrement lentes (en plus FAST est très instable). Mon idée serait de faire un tel calcul sur le GPU, car mon image source en provient. J'ai cherché des idées sur le Web pour écrire de tels shaders (j'utilise OpenGL ES 2.0), mais je n'ai rien trouvé de concret. Une idée comment je pourrais démarrer un tel algorithme?
image-processing
computer-vision
Stéphane Péchard
la source
la source
Réponses:
Sur quelle taille d'images travaillez-vous? À quelle fréquence d'images? Sur quel matériel? FAST est joli, euh, rapide dans mon expérience.
J'ai également vu FAST utilisé comme détecteur de ROI avec goodFeaturesToTrack exécuté sur les ROI identifiés pour fournir une meilleure stabilité sans exécuter la pénalité de gFTT sur l'image entière.
Le détecteur de coin "Harris" est également potentiellement très rapide car il est composé d'opérations très simples (pas de sqrt () par pixel par exemple!) - pas aussi stable que gFTT, mais peut-être plus que FAST.
(En termes d'implémentation GPU, Google
gpu corner
semble présenter beaucoup de liens, mais je n'ai aucune idée de leur adéquation - j'ai tendance à implémenter dans FPGA.)la source
Il se trouve que j'implémentais quelque chose comme ça sur OpenGL ES 2.0 en utilisant la détection de coin Harris, et bien que je ne sois pas complètement terminé, je pensais partager l'implémentation basée sur les shaders que j'ai jusqu'à présent. J'ai fait cela dans le cadre d'un framework open source basé sur iOS , vous pouvez donc consulter le code si vous êtes curieux de savoir comment fonctionne une étape particulière.
Pour ce faire, j'utilise les étapes suivantes:
Calculez les dérivées X et Y en soustrayant les valeurs du canal rouge des pixels gauche et droit et au-dessus et en dessous du pixel actuel. Je stocke ensuite la dérivée x au carré dans le canal rouge, la dérivée Y au carré dans le canal vert et le produit des dérivés X et Y dans le canal bleu. Le fragment shader pour cela ressemble à ceci:
où les variations ne sont que les coordonnées de texture décalées dans chaque direction. Je les précalcule dans le vertex shader pour éliminer les lectures de texture dépendantes, qui sont notoirement lentes sur ces GPU mobiles.
Appliquez un flou gaussien à cette image dérivée. J'ai utilisé un flou horizontal et vertical séparé, et profite du filtrage de texture matériel pour faire un flou à neuf coups avec seulement cinq lectures de texture à chaque passage. Je décris ce shader dans cette réponse Stack Overflow .
Exécutez le calcul de détection de coin Harris réel en utilisant les valeurs dérivées d'entrée floues. Dans ce cas, j'utilise en fait le calcul décrit par Alison Noble dans son doctorat. dissertation "Descriptions des surfaces d'images". Le shader qui gère cela ressemble à ceci:
Effectuez une suppression locale non maximale et appliquez un seuil pour mettre en surbrillance les pixels qui passent. J'utilise le shader de fragment suivant pour échantillonner les huit pixels au voisinage d'un pixel central et identifier s'il s'agit ou non du maximum dans ce regroupement:
Ce processus génère une carte de cornerness à partir de vos objets qui ressemble à ceci:
Les points suivants sont identifiés comme des coins basés sur la suppression et le seuillage non maximum:
Avec des seuils appropriés définis pour ce filtre, il peut identifier les 16 coins de cette image, bien qu'il ait tendance à placer les coins à environ un pixel à l'intérieur des bords réels de l'objet.
Sur un iPhone 4, cette détection de coin peut être exécutée à 20 FPS sur des images vidéo 640x480 provenant de la caméra, et un iPhone 4S peut facilement traiter des vidéos de cette taille à 60+ FPS. Cela devrait être beaucoup plus rapide que le traitement lié au processeur pour une tâche comme celle-ci, bien que le processus de lecture des points soit actuellement lié au processeur et un peu plus lent qu'il ne devrait l'être.
Si vous voulez voir cela en action, vous pouvez récupérer le code de mon framework et exécuter l'exemple FilterShowcase qui l'accompagne. L'exemple de détection de coin Harris fonctionne sur la vidéo en direct de la caméra de l'appareil, bien que, comme je l'ai mentionné, la lecture des points de coin se produise actuellement sur le processeur, ce qui ralentit vraiment cela. Je passe également à un processus basé sur GPU.
la source
Les détecteurs de coin "robustes" comme Shi-Tomasi et Moravec sont notoirement lents. vérifiez-les ici - http://en.wikipedia.org/wiki/Corner_detection FAST est probablement le seul détecteur de coin assez bon et léger. Vous pouvez améliorer FAST en effectuant une suppression non maximale - choisissez la sortie FAST avec le meilleur score de "cornerness" (il existe plusieurs façons intuitives de le calculer, y compris Shi-Tomasi et Moravec comme score de cornerness). Vous avez également le choix entre plusieurs détecteurs FAST - de FAST-5 à FAST-12 et FAST_ER (le dernier est probablement trop énorme pour les mobiles) Une autre façon est de générer FAST - obtenez le générateur de code FAST depuis le site de l'auteur et entraînez-le sur l'ensemble des images probables. http://www.edwardrosten.com/work/fast.html
la source
Pas vraiment spécifique au GPU, mais l' algorithme SUSAN de Steve Smith est bon pour la détection des coins.
L'algorithme est assez simple, comme le montre le code source en C.
la source