Question Traitement d'image: Amélioration de l'algorithme pour la reconnaissance de 'Coca-Cola Can'


L'un des projets les plus intéressants sur lesquels j'ai travaillé ces deux dernières années était un projet traitement d'image. L'objectif était de développer un système permettant de reconnaître Coca-Cola «canettes» (notez que je souligne le mot «canettes», vous verrez pourquoi dans une minute). Vous pouvez voir un exemple ci-dessous, avec la boîte reconnue dans le rectangle vert avec échelle et rotation.

Template matching

Quelques contraintes sur le projet:

  • L'arrière-plan pourrait être très bruyant.
  • le pouvez pourrait avoir échelle ou rotation ou même orientation (dans des limites raisonnables).
  • L'image peut avoir un certain degré de flou (les contours peuvent ne pas être entièrement droits).
  • Il pourrait y avoir des bouteilles de Coca-Cola dans l'image, et l'algorithme devrait seulement détecter le pouvez!
  • La luminosité de l'image peut varier énormément (vous ne pouvez donc pas compter "trop" sur la détection des couleurs).
  • le pouvez pourrait être partiellement caché sur les côtés ou au milieu et peut-être partiellement caché derrière une bouteille.
  • Il pourrait y avoir aucun pouvez du tout dans l'image, auquel cas vous n'avez rien trouvé et écrire un message le disant.

Vous pourriez donc vous retrouver avec des choses compliquées comme celle-ci (dans ce cas, mon algorithme a totalement échoué):

Total fail

J'ai fait ce projet il y a un certain temps, et je me suis beaucoup amusé à le faire, et j'ai eu une mise en œuvre décente. Voici quelques détails sur ma mise en œuvre:

La langue: Fait en C ++ en utilisant OpenCV bibliothèque.

Pré-traitement: Pour le pré-traitement de l'image, c'est-à-dire la transformation de l'image en une forme plus brute à donner à l'algorithme, j'ai utilisé deux méthodes:

  1. Changement de domaine de couleur de RGB à HSV et le filtrage basé sur la teinte "rouge", la saturation au-dessus d'un certain seuil pour éviter les couleurs de type orange, et le filtrage de faible valeur pour éviter les tons sombres. Le résultat final était une image binaire en noir et blanc, où tous les pixels blancs représenteraient les pixels qui correspondent à ce seuil. Évidemment, il y a encore beaucoup de merde dans l'image, mais cela réduit le nombre de dimensions avec lesquelles vous devez travailler. Binarized image 
  2. Filtrage du bruit en utilisant un filtrage médian (en prenant la valeur de pixel médiane de tous les voisins et en remplaçant le pixel par cette valeur) pour réduire le bruit.
  3. En utilisant Filtre de détection Canny Edge pour obtenir les contours de tous les éléments après 2 étapes précédentes. Contour detection

Algorithme: L'algorithme que j'ai choisi pour cette tâche a été pris à partir de ce livre impressionnant sur l'extraction de fonctionnalités et appelé Transformée de Hough généralisée (assez différent de la Hough Transform régulière). Il dit essentiellement quelques choses:

  • Vous pouvez décrire un objet dans l'espace sans connaître son équation analytique (ce qui est le cas ici).
  • Il résiste aux déformations d'image telles que la mise à l'échelle et la rotation, car il testera fondamentalement votre image pour chaque combinaison de facteur d'échelle et de facteur de rotation.
  • Il utilise un modèle de base (un modèle) que l'algorithme va "apprendre".
  • Chaque pixel restant dans l'image de contour va voter pour un autre pixel qui sera soi-disant le centre (en termes de gravité) de votre objet, basé sur ce qu'il a appris du modèle.

En fin de compte, vous obtenez une carte thermique des votes, par exemple ici tous les pixels du contour de la boîte vont voter pour son centre gravitationnel, donc vous aurez beaucoup de votes dans le même pixel correspondant à la centre, et verra un pic dans la carte de chaleur comme ci-dessous:

GHT

Une fois que vous avez cela, une simple heuristique basée sur un seuil peut vous donner l'emplacement du pixel central, à partir duquel vous pouvez dériver l'échelle et la rotation, puis tracer votre petit rectangle autour de lui (échelle finale et facteur de rotation modèle original). En théorie au moins ...

Résultats: Maintenant, alors que cette approche fonctionnait dans les cas de base, il manquait gravement dans certains domaines:

  • C'est extrêmement lent! Je ne le souligne pas assez. Il a fallu près d'une journée complète pour traiter les 30 images de test, évidemment parce que j'avais un facteur d'échelle très élevé pour la rotation et la traduction, car certaines des boîtes étaient très petites.
  • Il était complètement perdu quand les bouteilles étaient dans l'image, et pour une raison quelconque, presque toujours trouvé la bouteille au lieu de la boîte (peut-être parce que les bouteilles étaient plus grandes, donc plus de pixels, donc plus de votes)
  • Les images floues n'étaient également pas bonnes, car les votes se sont retrouvés en pixel dans des endroits aléatoires autour du centre, se terminant ainsi par une carte de chaleur très bruyante.
  • La variance de la translation et de la rotation a été atteinte, mais pas en orientation, ce qui signifie qu'une boîte qui n'était pas directement en face de l'objectif de la caméra n'a pas été reconnue.

Pouvez-vous m'aider à améliorer mon spécifique algorithme, en utilisant exclusivement OpenCV caractéristiques, pour résoudre le quatre spécifiques problèmes mentionnés?

J'espère que certaines personnes apprendront aussi quelque chose, après tout, je pense que non seulement les personnes qui posent des questions devraient apprendre. :)


1390
2018-04-16 04:23


origine


Réponses:


Une approche alternative consisterait à extraire les caractéristiques (points-clés) en utilisant transformation d'entité invariable à l'échelle (SIFT) ou Accéléré Caractéristiques robustes (LE SURF).

Il est implémenté dans OpenCV 2.3.1.

Vous pouvez trouver un exemple de code sympa en utilisant des fonctionnalités dans Features2D + Homographie pour trouver un objet connu

Les deux algorithmes sont invariants pour la mise à l'échelle et la rotation. Depuis qu'ils travaillent avec des fonctionnalités, vous pouvez également gérer occlusion (tant que suffisamment de keypoints sont visibles).

Enter image description here

Source de l'image: exemple de tutoriel

Le traitement prend quelques centaines de ms pour SIFT, SURF est un peu plus rapide, mais il ne convient pas aux applications en temps réel. ORB utilise FAST qui est plus faible en ce qui concerne l'invariance de rotation.

Les papiers originaux


563
2018-04-16 05:17



Pour accélérer les choses, je profite du fait qu'on ne vous demande pas de trouver une image / un objet arbitraire, mais spécifiquement un logo Coca-Cola. Ceci est important parce que ce logo est très distinctif, et il devrait avoir une signature caractéristique, invariable à l'échelle dans le domaine fréquentiel, en particulier dans le canal rouge de RVB. C'est-à-dire que l'alternance rouge-blanc-rouge rencontrée par une ligne de balayage horizontal (entraînée sur un logo aligné horizontalement) aura un "rythme" distinctif lorsqu'elle passera par l'axe central du logo. Ce rythme «accélérera» ou «ralentira» à différentes échelles et orientations, mais restera proportionnellement équivalent. Vous pouvez identifier / définir quelques dizaines de lignes de balayage, à la fois horizontalement et verticalement à travers le logo et plusieurs autres en diagonale, dans un motif en étoile. Appelez-les les "lignes de balayage de signature".

Signature scan line

La recherche de cette signature dans l'image cible est une simple question de numériser l'image en bandes horizontales. Recherchez une haute fréquence dans le canal rouge (indiquant le passage d'une région rouge à une région blanche), et une fois trouvée, voyez si elle est suivie par l'un des rythmes de fréquence identifiés dans la session d'entraînement. Une fois qu'une correspondance est trouvée, vous saurez instantanément l'orientation et l'emplacement de la ligne de numérisation dans le logo (si vous gardez une trace de ces choses pendant l'entraînement), identifier les limites du logo à partir de là est donc trivial.

Je serais surpris si ce n'était pas un algorithme linéairement efficace, ou presque. Évidemment, cela n'aborde pas la question de la discrimination de votre bouteille, mais au moins, vous aurez vos logos.

(Mise à jour: pour la reconnaissance de bouteille je chercherais du coke (le liquide brun) adjacent au logo - c'est-à-dire, à l'intérieur la bouteille. Ou, dans le cas d'une bouteille vide, je chercherais un casquette qui aura toujours la même forme de base, la même taille et la même distance par rapport au logo et sera généralement tout blanc ou rouge. Rechercher une forme elliptique de couleur solide où un bouchon devrait être, par rapport au logo. Pas infaillible bien sûr, mais votre objectif ici devrait être de trouver le facile ceux vite.)

(Cela fait quelques années que j'ai passé mes jours de traitement d'image, j'ai donc gardé cette suggestion de haut niveau et conceptuelle, je pense qu'elle pourrait légèrement approximer la façon dont un œil humain pourrait fonctionner - ou du moins comment mon cerveau fonctionne!)


331
2018-04-17 21:06



Problème amusant: quand j'ai jeté un coup d'œil à l'image de votre bouteille, je pensais que c'était une canette aussi. Mais, en tant qu'humain, ce que j'ai fait pour faire la différence c'est que j'ai alors remarqué que c'était aussi une bouteille ...

Donc, pour distinguer les cannettes et les bouteilles, pourquoi ne pas tout d'abord rechercher les bouteilles? Si vous en trouvez un, masquer l'étiquette avant de chercher des canettes.

Pas trop difficile à implémenter si vous faites déjà des canettes. Le vrai inconvénient est qu'il double votre temps de traitement. (Mais en pensant aux applications du monde réel, vous finirez par vouloir faire des bouteilles de toute façon ;-)


132
2018-04-16 05:03



N'est-il pas difficile, même pour les humains, de faire la distinction entre une bouteille et une boîte dans la deuxième image (à condition que la partie transparente de la bouteille soit cachée)?

Ils sont presque identiques à l'exception d'une très petite région (c'est-à-dire, la largeur au sommet de la canette est un peu petite alors que l'enveloppe de la bouteille est de la même largeur, mais un changement mineur?)

La première chose qui me vint à l'esprit fut de vérifier le haut rouge de la bouteille. Mais c'est toujours un problème, s'il n'y a pas de top pour la bouteille, ou si elle est partiellement cachée (comme mentionné plus haut).

La deuxième chose que je pensais était à propos de la transparence de la bouteille. OpenCV a quelques travaux sur la recherche d'objets transparents dans une image. Vérifiez les liens ci-dessous.

Particulièrement regarder ceci pour voir avec quelle précision ils détectent le verre:

Voir leur résultat d'implantation:

Enter image description here

Ils disent que c'est la mise en œuvre du document "Un cadre géodésique de contour actif pour trouver le verre" par K. McHenry et J. Ponce, CVPR 2006.

Il pourrait être utile dans votre cas un peu, mais le problème se pose à nouveau si la bouteille est remplie.

Je pense donc ici, vous pouvez d'abord chercher le corps transparent des bouteilles ou pour une région rouge reliée à deux objets transparents latéralement qui est évidemment la bouteille. (Lorsque vous travaillez idéalement, une image comme suit.)

Enter image description here

Maintenant, vous pouvez supprimer la zone jaune, c'est-à-dire l'étiquette de la bouteille et exécuter votre algorithme pour trouver la boîte.

Quoi qu'il en soit, cette solution a aussi des problèmes différents comme dans les autres solutions.

  1. Cela ne fonctionne que si votre bouteille est vide. Dans ce cas, vous devrez rechercher la région rouge entre les deux couleurs noires (si le liquide Coca Cola est noir).
  2. Un autre problème si la partie transparente est couverte.

Mais de toute façon, s'il n'y a aucun des problèmes ci-dessus dans les images, cela semble être une meilleure façon.


101
2018-04-18 23:02



J'aime vraiment Darren Cook's et les réponses du stacker à ce problème. J'étais en train de jeter un coup d'œil sur mes pensées, mais je crois que mon approche est trop en forme pour ne pas partir d'ici.

En bref, vous avez identifié un algorithme pour déterminer qu'un logo Coca-Cola est présent à un endroit particulier dans l'espace. Vous essayez maintenant de déterminer, pour des orientations arbitraires et des facteurs d'échelle arbitraires, une heuristique appropriée pour distinguer Coca-Cola canettes d'autres objets, y compris: bouteilles, panneaux d'affichage, annonces, et L'attirail de Coca-Cola tous associés à ce logo iconique. Vous n'avez pas appelé beaucoup de ces cas supplémentaires dans votre énoncé de problème, mais je pense qu'ils sont essentiels au succès de votre algorithme.

Le secret ici est de déterminer quelles caractéristiques visuelles un pouvez contient ou, à travers l'espace négatif, quelles caractéristiques sont présentes pour les autres produits Coke qui ne sont pas présents dans les canettes. À cette fin, la meilleure réponse actuelle esquisse une approche de base pour sélectionner "peut" si et seulement si "bouteille" n'est pas identifié, soit par la présence d'un bouchon de bouteille, liquide, ou d'autres heuristiques visuelles similaires.

Le problème est que cela tombe en panne. Une bouteille peut, par exemple, être vide et ne pas présenter de bouchon, ce qui conduit à un faux positif. Ou, ça pourrait être une bouteille partielle avec des fonctionnalités supplémentaires mutilées, conduisant à nouveau à une fausse détection. Inutile de dire que ce n'est pas élégant, ni efficace pour nos besoins.

À cette fin, les critères de sélection les plus corrects pour les canettes semblent être les suivants:

  • Est la forme de la silhouette de l'objet, comme vous avez esquissé dans votre question, correct? Si oui, +1.
  • Si nous supposons la présence de lumière naturelle ou artificielle, détecte-t-on un contour de chrome à la bouteille qui indique si elle est faite d'aluminium? Si oui, +1.
  • Est-ce que nous déterminons que propriétés spéculaires de l'objet sont corrects, par rapport à nos sources lumineuses (lien vidéo illustratif sur détection de la source lumineuse)? Si oui, +1.
  • Pouvons-nous déterminer d'autres propriétés de l'objet qui l'identifient comme une boîte, y compris, mais sans s'y limiter, l'inclinaison de l'image topologique du logo, l'orientation de l'objet, la juxtaposition de l'objet (par exemple, sur une surface plane comme une table ou dans le contexte d'autres boîtes), et la présence d'une tirette? Si oui, pour chacun, +1.

Votre classification pourrait alors ressembler à ceci:

  • Pour chaque correspondance candidate, si la présence d'un logo Coca Cola a été détectée, tracez une bordure grise.
  • Pour chaque match sur +2, tracez une bordure rouge.

Ceci met visuellement en évidence chez l'utilisateur ce qui a été détecté, en mettant l'accent sur les positifs faibles qui peuvent, correctement, être détectés comme des boîtes mutilées.

La détection de chaque propriété comporte une complexité de temps et d'espace très différente, et pour chaque approche, un passage rapide à travers http://dsp.stackexchange.com est plus que raisonnable pour déterminer l'algorithme le plus correct et le plus efficace pour vos fins. Mon intention ici est, purement et simplement, de souligner que détecter si quelque chose est un can en invalidant une petite partie de l'espace de détection candidat n'est pas la solution la plus robuste ou efficace à ce problème, et idéalement, vous devriez prendre les mesures appropriées en conséquence.

Et bon, félicitations l'article de Hacker News! Dans l'ensemble, c'est une très bonne question digne de la publicité qu'elle a reçue. :)


41
2018-04-22 22:56



Regarder la forme

Jetez un coup d'oeil à la forme de la partie rouge de la canette / bouteille. Remarquez comment la boîte se rétrécit légèrement tout en haut tandis que l'étiquette de la bouteille est droite. Vous pouvez distinguer entre ces deux en comparant la largeur de la partie rouge à travers la longueur de celui-ci.

Regarder les faits saillants

Une façon de distinguer les bouteilles et les canettes est le matériau. Une bouteille est faite de plastique tandis qu'une boîte est faite de métal d'aluminium. Dans des situations suffisamment bien éclairées, regarder la spécularité serait une façon de distinguer une étiquette de bouteille d'une étiquette de boîte.

Autant que je sache, c'est ainsi qu'un humain ferait la différence entre les deux types d'étiquettes. Si les conditions d'éclairage sont médiocres, il y aura forcément une certaine incertitude dans la distinction des deux. Dans ce cas, vous devriez être capable de détecter la présence de la bouteille transparente / translucide elle-même.


35
2018-04-16 08:31



S'il vous plaît jeter un oeil à Zdenek Kalal Predator tracker. Cela nécessite une certaine formation, mais il peut apprendre activement comment l'objet suivi regarde différentes orientations et échelles et le fait en temps réel!

Le code source est disponible sur son site. C'est dedans MATLAB, mais il y a peut-être déjà une implémentation Java faite par un membre de la communauté. J'ai ré-implémenté avec succès la partie tracker de TLD en C #. Si je me souviens bien, TLD utilise Ferns comme détecteur de point-clé. J'utilise à la place SURF ou SIFT (déjà suggéré par @stacker) pour réacquérir l'objet s'il a été perdu par le tracker. Les retours d'expérience du tracker permettent de construire facilement avec le temps une liste dynamique de templates de sift / surf qui permettent avec le temps de réacquérir l'objet avec une très grande précision.

Si vous êtes intéressé par ma mise en œuvre C # du tracker, n'hésitez pas à demander.


31
2018-04-17 20:56



Si vous n'êtes pas limité à une caméra qui n'était pas dans l'une de vos contraintes peut-être vous pouvez passer à l'aide d'un capteur de portée comme la Xbox Kinect. Avec cela, vous pouvez effectuer une segmentation en profondeur et en couleur de l'image. Cela permet une séparation plus rapide des objets dans l'image. Vous pouvez ensuite utiliser ICP matching ou des techniques similaires pour faire correspondre la forme de la boîte plutôt que son contour ou sa couleur et étant donné qu'il est cylindrique, cela peut être une option valable pour toute orientation si vous avez déjà un scan 3D de la cible. Ces techniques sont souvent assez rapides surtout lorsqu'elles sont utilisées dans un but précis qui devrait résoudre votre problème de vitesse.

Aussi, je pourrais suggérer, pas nécessairement pour la précision ou la vitesse, mais pour le plaisir, vous pouvez utiliser un réseau de neurones formés sur votre image segmentée de teinte pour identifier la forme de la boîte. Ceux-ci sont très rapides et peuvent souvent être jusqu'à 80/90% précis. La formation serait un processus un peu long, bien que vous deviez identifier manuellement la boîte dans chaque image.


25
2018-04-16 04:54



Je détecterais des rectangles rouges: RGB -> HSV, filtre rouge -> image binaire, Fermer (dilater puis éroder, connu sous le nom imclose en matlab)

Ensuite, regardez à travers les rectangles du plus grand au plus petit. Les rectangles qui ont des rectangles plus petits dans une position / échelle connue peuvent tous deux être retirés (en supposant que les proportions des bouteilles sont constantes, le plus petit rectangle serait un bouchon de bouteille).

Cela vous laisserait avec des rectangles rouges, alors vous devrez d'une façon ou d'une autre détecter les logos pour dire s'ils sont un rectangle rouge ou un bidon de coke. Comme OCR, mais avec un logo connu?


20
2018-04-16 06:34



Cela peut être une idée très naïve (ou peut ne pas fonctionner du tout), mais les dimensions de toutes les canettes de coke sont fixes. Donc peut-être si la même image contient à la fois une canette et une bouteille, alors vous pouvez les différencier par des considérations de taille (les bouteilles vont être plus grandes). Maintenant, en raison de la profondeur manquante (c'est-à-dire de la cartographie 3D à la cartographie 2D), il est possible qu'une bouteille apparaisse rétrécie et qu'il n'y ait pas de différence de taille. Vous pouvez récupérer des informations de profondeur en utilisant stéréo-imagerie puis récupérez la taille d'origine.


19
2018-04-16 05:13