1776 votes

Traitement d'images : Amélioration de l'algorithme de reconnaissance des canettes de Coca-Cola

L'un des projets les plus intéressants sur lequel j'ai travaillé ces deux dernières années était un projet concernant traitement des images . L'objectif était de développer un système capable de reconnaître Coca-Cola "boîtes de conserve (notez que j'insiste sur le mot "boîtes", vous verrez pourquoi dans une minute). Vous pouvez voir un exemple ci-dessous, avec la boîte de conserve reconnue dans le champ rectangle vert avec échelle et rotation.

Template matching

Quelques contraintes sur le projet :

  • L'arrière-plan peut être très bruyant.
  • Le site peut pourrait avoir n'importe quel échelle ou rotation ou même l'orientation (dans des limites raisonnables).
  • L'image peut présenter un certain degré de flou (les contours peuvent ne pas être entièrement droits).
  • Il peut y avoir des bouteilles de Coca-Cola dans l'image, et l'algorithme ne doit détecter que les bouteilles de Coca-Cola. peut !
  • La luminosité de l'image peut varier considérablement (vous ne pouvez donc pas vous fier "trop" à la détection des couleurs).
  • Le site peut pourrait être partiellement caché sur les côtés ou au milieu et éventuellement partiellement caché derrière une bouteille.
  • Il ne pourrait y avoir peut du tout dans l'image, auquel cas vous deviez ne rien trouver et écrire un message le disant.

Vous pouvez donc vous retrouver avec des situations délicates comme celle-ci (qui, dans ce cas, a fait échouer mon algorithme) :

Total fail

J'ai fait ce projet il y a quelque temps, et j'ai eu beaucoup de plaisir à le faire, et j'ai eu une implémentation décente. Voici quelques détails sur mon implémentation :

Langue : Réalisé 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é 2 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 ressemblant à l'orange, et le filtrage de la faible valeur pour éviter les tons sombres. Le résultat final est une image binaire en noir et blanc, où tous les pixels blancs représentent les pixels qui correspondent à ce seuil. Il est évident qu'il y a encore beaucoup de saletés dans l'image, mais cela réduit le nombre de dimensions avec lesquelles vous devez travailler. Binarized image
  2. Filtrage du bruit à l'aide d'un filtre médian (on prend la valeur médiane du pixel de tous les voisins et on remplace le pixel par cette valeur) pour réduire le bruit.
  3. Utilisation de Filtre de détection des bords Canny 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 est tiré de ce livre impressionnant sur l'extraction de caractéristiques et appelé Transformée de Hough généralisée (assez différent de la transformation de Hough ordinaire). Elle dit essentiellement plusieurs choses :

  • On peut 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 de l'image telles que la mise à l'échelle et la rotation, car il testera votre image pour chaque combinaison de facteur d'échelle et de facteur de rotation.
  • Il utilise un modèle de base (un gabarit) que l'algorithme va "apprendre".
  • Chaque pixel restant dans l'image du contour votera pour un autre pixel qui sera supposé être le centre (en termes de gravité) de votre objet, sur la base de ce qu'il a appris du modèle.

Au final, vous obtenez une carte thermique des votes, par exemple ici tous les pixels du contour de la canette voteront pour son centre gravitationnel, vous aurez donc beaucoup de votes dans le même pixel correspondant au centre, et vous verrez un pic dans la carte thermique comme ci-dessous :

GHT

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

Résultats : Or, si cette approche fonctionnait dans les cas de base, elle présentait de graves lacunes dans certains domaines :

  • Il est extrêmement lent ! Je n'insiste pas assez sur ce point. Il a fallu presque une journée entière pour traiter les 30 images de test, évidemment parce que j'avais un facteur d'échelle très élevé pour la rotation et la translation, puisque certaines des boîtes de conserve étaient très petites.
  • Il était complètement perdu lorsqu'il y avait des bouteilles dans l'image, et pour une raison quelconque, il trouvait presque toujours la bouteille au lieu de la canette (peut-être parce que les bouteilles étaient plus grandes, donc avaient plus de pixels, donc plus de votes).
  • Les images floues n'étaient pas bonnes non plus, car les votes se retrouvaient dans les pixels à des endroits aléatoires autour du centre, ce qui donnait une carte thermique très bruyante.
  • L'invariance en translation et en rotation a été obtenue, mais pas en orientation, ce qui signifie qu'une canette qui ne faisait pas directement face à l'objectif de la caméra n'était pas reconnue.

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

J'espère que d'autres personnes en tireront également des enseignements. Après tout, je pense qu'il n'y a pas que ceux qui posent des questions qui doivent apprendre :)

48 votes

On pourrait dire que cette question est plus appropriée à dsp.stackexchange.com, ou stats.stackexchange.com, et vous devriez certainement envisager de reposer votre question sur ces sites également.

50 votes

La première chose à faire ici est d'analyser pourquoi les différents cas d'échec se produisent. Par exemple, isolez des exemples d'endroits où les bouteilles gagnent, où les images sont floues, etc., et effectuez une analyse statistique pour apprendre la différence entre leurs représentations de Hough et celles que vous souhaiteriez qu'il détecte. Voici d'excellents endroits pour découvrir des approches alternatives ici y ici

1 votes

@linker L'extraction des caractéristiques SIFT ou SURF ne serait-elle pas beaucoup plus rapide que la transformation de Hough ? Pourquoi ne détecter que des boîtes de conserve alors que l'on pourrait détecter davantage d'objets enregistrés ?

724voto

stacker Points 34209

Une autre approche consisterait à extraire des caractéristiques (points clés) en utilisant la méthode d'extraction des données. transformation de caractéristiques invariantes à l'échelle (SIFT) ou Fonctionnalités robustes accélérées (SURF).

Vous pouvez trouver une belle OpenCV exemple de code dans Java , C++ et Python sur cette page : _Features2D + Homographie pour trouver un objet connu_

Les deux algorithmes sont invariants à l'échelle et à la rotation. Puisqu'ils fonctionnent avec des caractéristiques, vous pouvez aussi manipuler occlusion (tant que suffisamment de points clés sont visibles).

Enter image description here

Source d'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 documents originaux

2 votes

Ça a l'air intéressant. Cet algorithme gère-t-il également l'invariance d'orientation (c'est-à-dire si la boîte ne fait pas directement face à l'objectif de la caméra) ? C'est l'un des points majeurs où mon algorithme a échoué.

0 votes

@linker vous pourriez prendre quelques photos de l'objet 3D en le faisant tourner (autour de l'axe des y de l'objet). Comme les images d'une boîte sont différentes de l'avant et de l'arrière, vous pourriez essayer de trouver la correspondance la plus proche et estimer son orientation dans les cas où le logo n'est pas entièrement visible.

0 votes

Idéalement, j'aimerais appliquer cet algorithme dans le cas d'images échantillonnées de manière aléatoire, où je n'ai qu'une simple image jpeg ou png. Cet algorithme fonctionnerait-il toujours dans ce cas, ou ai-je besoin d'images spéciales ?

415voto

kmote Points 3948

Pour accélérer les choses, je profiterais du fait qu'on ne vous demande pas de trouver une image/un objet arbitraire, mais spécifiquement un objet avec le logo Coca-Cola. C'est important car ce logo est très distinctif et il devrait avoir une signature caractéristique, invariante à l'échelle, dans le domaine des fréquences, en particulier dans le canal rouge de RVB. En d'autres termes, le motif alternatif de rouge à blanc à rouge rencontré par une ligne de balayage horizontale (formée sur un logo aligné horizontalement) aura un "rythme" distinctif lorsqu'il passera par l'axe central du logo. Ce rythme s'accélérera ou se ralentira selon l'échelle et l'orientation, mais restera proportionnellement équivalent. Vous pouvez identifier/définir quelques douzaines de ces 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 la signature".

Signature scan line

La recherche de cette signature dans l'image cible est une simple question de balayage de l'image en bandes horizontales. Recherchez une haute fréquence dans le canal rouge (indiquant le déplacement d'une région rouge vers une région blanche), et une fois trouvée, regardez si elle est suivie par l'un des rythmes de fréquence identifiés lors de la session de formation. Une fois qu'une correspondance est trouvée, vous connaîtrez instantanément l'orientation et l'emplacement de la ligne de balayage dans le logo (si vous en tenez compte pendant la formation), de sorte que l'identification des limites du logo à partir de là est triviale.

Je serais surpris que cet algorithme ne soit pas linéairement efficace, ou presque. Il ne résout évidemment pas le problème de la discrimination entre les canettes et les bouteilles, mais au moins vous aurez vos logos.

(Mise à jour : pour reconnaître la bouteille, je chercherais le coca (le liquide brun) à côté du logo - c'est-à-dire, à l'intérieur de la bouteille. Ou, dans le cas d'une bouteille vide, je chercherais une capuchon qui auront toujours la même forme de base, la même taille et la même distance par rapport au logo et seront généralement tout blancs ou rouges. Recherchez une forme elliptique de couleur unie où un capuchon debe être, par rapport au logo. Ce n'est pas infaillible, bien sûr, mais votre objectif ici devrait être de trouver la meilleure position pour le logo. facile ceux rapide .)

(Cela fait quelques années que je n'ai pas fait de traitement d'images, donc j'ai gardé cette suggestion de haut niveau et conceptuelle. Je pense qu'elle pourrait se rapprocher légèrement de la façon dont un œil humain pourrait fonctionner - ou du moins de la façon dont mon cerveau fonctionne).

28 votes

C'est une excellente suggestion, j'aime particulièrement le fait que cet algorithme devrait être assez rapide, même s'il aura probablement beaucoup de faux négatifs. Un de mes objectifs cachés est d'utiliser cette détection en temps réel pour la robotique, donc cela pourrait être un bon compromis !

45 votes

Oui, on oublie souvent (dans un domaine caractérisé par la précision) que approximation sont essentiels pour la plupart des tâches de modélisation en temps réel dans le monde réel. (J'ai basé mon thèse sur ce concept). Gardez vos algorithmes gourmands en temps pour des régions limitées (pour éliminer les faux positifs). Et n'oubliez pas : en robotique, vous n'êtes généralement pas limité à une seule image. Dans le cas d'un robot mobile, un algorithme rapide peut rechercher des dizaines d'images sous différents angles en moins de temps que les algorithmes sophistiqués ne le feraient sur une seule image, ce qui réduit considérablement les faux négatifs.

30 votes

J'aime l'idée d'utiliser ce qui revient à un scanner de code-barres pour extrêmement rapide détection des logos de Coca-Cola. +1 !

175voto

Darren Cook Points 5743

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

Donc, pour distinguer les canettes des bouteilles, pourquoi ne pas commencer par scanner les bouteilles ? Si vous en trouvez une, masquez l'étiquette avant de chercher les boîtes de conserve.

Pas trop difficile à mettre en œuvre si vous faites déjà des boîtes de conserve. Le véritable inconvénient est que cela 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 ;-)

7 votes

Oui, j'y ai pensé aussi, mais je n'ai pas eu beaucoup de temps pour le faire. Comment reconnaître une bouteille, puisque sa partie principale ressemble à une boîte de conserve à l'échelle ? Je pensais aussi chercher le bouchon rouge et voir s'il est aligné avec le centre de la bouteille, mais cela ne semble pas très solide.

47 votes

S'il y a un bouchon (ou un anneau) rouge parallèle au "Coca cola", il s'agit très probablement d'une bouteille.

0 votes

@linker Comment avez-vous formé votre algorithme pour les boîtes de conserve ? Aviez-vous des exemples de boîtes de conserve ? Et si vous vous entraîniez avec des exemples de bouteilles ?

142voto

Abid Rahman K Points 18045

N'est-il pas difficile, même pour un être humain, de faire la distinction entre une bouteille et une canette sur la deuxième image (à condition que la zone transparente de la bouteille soit cachée) ?

Elles sont presque identiques à l'exception d'une toute petite région (c'est-à-dire que la largeur au sommet de la canette est un peu plus petite alors que l'enveloppe de la bouteille est de la même largeur partout, mais un changement mineur n'est-ce pas ?)

La première chose qui m'est venue à l'esprit a été de vérifier la présence du bouchon rouge de la bouteille. Mais il y a toujours un problème, s'il n'y a pas de bouchon pour la bouteille, ou s'il est partiellement caché (comme mentionné ci-dessus).

La deuxième chose à laquelle j'ai pensé est la transparence de la bouteille. OpenCV a quelques travaux sur la recherche d'objets transparents dans une image. Consultez les liens ci-dessous.

Regardez en particulier ceci pour voir avec quelle précision ils détectent le verre :

Voir le résultat de leur mise en œuvre :

Enter image description here

Ils disent que c'est la mise en œuvre du papier "A Geodesic Active Contour Framework for Finding Glass" par K. McHenry et J. Ponce, CVPR 2006 .

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

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

Enter image description here

Vous pouvez maintenant supprimer la région jaune, c'est-à-dire l'étiquette de la bouteille, et exécuter votre algorithme pour trouver la canette.

Quoi qu'il en soit, cette solution présente également différents problèmes comme dans les autres solutions.

  1. Cela ne fonctionne que si votre bouteille est vide. Dans ce cas, vous devrez chercher 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 photos, cela semble être une meilleure solution.

0 votes

+1 J'ai pensé à cela et j'étais sur le point de mettre en œuvre cette approche. Cependant, @linker devrait partager son ensemble d'images afin que nous puissions essayer de faire des suppositions plus éclairées.

0 votes

Ouais je pense aussi que c'est bien s'il y avait plus d'images.

0 votes

Si nous ne disposons que des étiquettes des bouteilles et des boîtes de conserve et que nous n'avons pas les autres facteurs distinctifs tels que le bouchon de la bouteille, la transparence ou le haut et le bas de la boîte, la largeur de la bouteille est différente de celle de la boîte.

54voto

MrGomez Points 20526

J'aime vraiment Darren Cook's y Réponses de l'empileur à ce problème. J'étais en train de jeter mes pensées dans un commentaire à ce sujet, mais je crois que mon approche est trop en forme de réponse pour ne pas la laisser ici.

En résumé, vous avez identifié un algorithme permettant de déterminer qu'un logo Coca-Cola est présent à un endroit particulier de l'espace. Vous essayez maintenant de déterminer, pour des orientations arbitraires et des facteurs d'échelle arbitraires, une heuristique permettant de distinguer le logo Coca-Cola de celui des autres produits. boîtes de conserve d'autres objets, y compris : bouteilles , panneaux d'affichage , annonces et L'attirail Coca-Cola tous associés à ce logo emblématique. Vous n'avez pas mentionné beaucoup de ces cas supplémentaires dans votre énoncé du problème, mais je pense qu'ils sont essentiels au succès de votre algorithme.

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

Le problème, c'est que cela se casse la figure. Une bouteille peut, par exemple, être vide et ne pas présenter de bouchon, ce qui entraîne un faux positif. Ou bien, elle pourrait être une bouteille partielle avec des caractéristiques supplémentaires maniées, ce qui conduit à 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 boîtes de conserve semblent être les suivants :

  • Est la forme de la silhouette de l'objet, comme que vous avez esquissé dans votre question n'est-ce pas ? Si oui, +1.
  • Si nous supposons la présence d'une lumière naturelle ou artificielle, détectons-nous un contour chromé sur la bouteille qui indique si celle-ci est en aluminium ? Si oui, +1.
  • Déterminons-nous que le propriétés spéculaires de l'objet sont correctes, par rapport à nos sources de lumière ( lien vidéo illustratif en détection de la source lumineuse ) ? Si oui, +1.
  • Pouvons-nous déterminer d'autres propriétés de l'objet qui permettent de l'identifier comme une canette, y compris, mais sans s'y limiter, l'inclinaison topologique de l'image 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 canettes), et la présence d'une tirette ? Si oui, pour chacun d'eux, +1.

Votre classification pourrait alors ressembler à ce qui suit :

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

Cela met visuellement en évidence pour l'utilisateur ce qui a été détecté, en soulignant les faibles positifs qui peuvent, à juste titre, être détectés comme des boîtes de conserve mutilées.

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

Et hey, félicitations pour le post de Hacker News ! Dans l'ensemble, il s'agit d'une question assez formidable qui mérite la publicité qu'elle a reçue :)

2 votes

C'est une approche intéressante qui vaut au moins la peine d'être essayée. J'aime beaucoup votre raisonnement sur le problème.

1 votes

C'est un peu ce que je pensais : ne pas exclure certains types de faux positifs. Exclure d'autres caractéristiques de ce qui fait une canette de coca. Mais je me demande : que faites-vous d'une canette écrasée ? Je veux dire, si vous marchez sur une canette de coca, c'est toujours une canette de coca. Mais elle n'aura plus la même forme. Ou bien ce problème est-il AI-Complet ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X