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




traitement d image en c++ pdf (20)

L'un des projets les plus intéressants sur lesquels j'ai travaillé ces dernières années était un projet sur le traitement d'image . L'objectif était de développer un système permettant de reconnaître les «cannettes» de Coca-Cola (notez que j'insiste sur 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.

Quelques contraintes sur le projet:

  • L'arrière-plan pourrait être très bruyant.
  • La boîte pourrait avoir n'importe quelle é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 la canette !
  • La luminosité de l'image peut varier énormément (vous ne pouvez donc pas compter "trop" sur la détection des couleurs).
  • La boîte pourrait être partiellement cachée sur les côtés ou au milieu et peut-être partiellement cachée derrière une bouteille.
  • Il ne pouvait y avoir aucune boîte dans l'image, auquel cas vous ne deviez rien trouver 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é):

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:

Langue : Fait en C ++ en utilisant la bibliothèque OpenCV .

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 en HSV et filtrage basé sur la teinte "rouge", saturation au-dessus d'un certain seuil pour éviter les couleurs de type orange, et 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.
  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. Utilisation de Canny Edge Detection Filter pour obtenir les contours de tous les éléments après 2 étapes précédentes.

Algorithme : L'algorithme que j'ai choisi pour cette tâche a été tiré de this livre génial sur l'extraction de caractéristiques et appelé Transformée de Hough Généralisée (assez différent de la Transformée Hough ordinaire). 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:

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, même si cette approche fonctionnait dans les cas de base, elle manquait cruellement 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.
  • Une variance de la translation et de la rotation a été obtenue, mais pas dans l'orientation, ce qui signifie qu'une boîte qui ne faisait pas directement face à l'objectif de la caméra n'a pas été reconnue.

Pouvez-vous m'aider à améliorer mon algorithme spécifique , en utilisant exclusivement des fonctionnalités OpenCV , pour résoudre les quatre problèmes spécifiques 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. :)


J'aime le défi et je voulais donner une réponse, ce qui résout le problème, je pense.

  1. Extraction des caractéristiques (points-clés, descripteurs tels que SIFT, SURF) du logo
  2. Faites correspondre les points avec une image de modèle du logo (en utilisant Matcher tel que Brute Force)
  3. Estimer les coordonnées du corps rigide (problème PnP - SolvePnP)
  4. Estimer la position du bouchon en fonction du corps rigide
  5. Faire une rétroprojection et calculer la position du pixel de l'image (ROI) du bouchon de la bouteille (je suppose que vous avez les paramètres intrinsèques de la caméra)
  6. Vérifiez avec une méthode si le bouchon est là ou non. Si là, alors c'est la bouteille

La détection du bouchon est un autre problème. Cela peut être compliqué ou simple. Si j'étais vous, je vérifierais simplement l'histogramme de couleur dans le ROI pour une décision simple.

S'il vous plaît, donnez votre avis si j'ai tort. Merci.


Vous avez besoin d'un programme qui apprend et améliore la précision de la classification organiquement à partir de l'expérience.

Je vais suggérer un apprentissage profond, avec un apprentissage en profondeur, cela devient un problème trivial.

Vous pouvez recycler le modèle initial v3 sur Tensorflow:

Comment recycler le calque final d'Inception pour de nouvelles catégories .

Dans ce cas, vous allez former un réseau de neurones convolutionnels pour classer un objet comme un coca-cola ou non.


Une approche alternative consisterait à extraire des entités (keypoints) à l'aide de la fonction de transformation invariable à l' échelle (SIFT) ou des fonctions robustes accélérées (SURF).

Il est implémenté dans OpenCV 2.3.1.

Vous pouvez trouver un bel exemple de code en utilisant les fonctionnalités de Features2D + Homography pour trouver un objet connu

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

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


J'ai quelques années de retard pour répondre à cette question. Avec l'état de l'art poussé à ses limites par les CNN au cours des 5 dernières années, je n'utiliserais pas OpenCV pour faire cette tâche maintenant! ( Je sais que vous vouliez spécifiquement des fonctionnalités OpenCv dans la question ) Je pense que les algorithmes de détection d'objets tels que Faster-RCNN, YOLO, SSD, etc., auraient un problème avec une marge significative par rapport aux fonctionnalités OpenCV. Si je devais résoudre ce problème maintenant (après 6 ans !!) j'utiliserais certainement Faster-RCNN .


Hmm, je pense vraiment que je suis sur quelque chose (c'est comme la question la plus intéressante de tous les temps - donc il serait dommage de ne pas continuer à essayer de trouver la réponse "parfaite", même si une réponse acceptable a été trouvée). .

Une fois que vous avez trouvé le logo, vos problèmes sont à moitié terminés. Ensuite, vous n'avez qu'à comprendre les différences entre ce qui est autour du logo. De plus, nous voulons faire le moins de choses possible. Je pense que c'est en fait cette partie facile ...

Qu'est - ce qui entoure le logo? Pour une canette, on peut voir du métal qui, malgré les effets de l'éclairage, ne change pas du tout dans sa couleur de base. Tant que nous connaissons l'angle de l'étiquette, nous pouvons dire ce qui est directement au-dessus, donc nous regardons la différence entre ceux-ci:

Ici, ce qui est au-dessus et au-dessous du logo est complètement sombre, de couleur constante. Relativement facile à cet égard.

Ici, ce qui est au-dessus et au-dessous est léger, mais toujours cohérent en couleur. C'est tout argent, et le métal tout argent semble en fait assez rare, ainsi que les couleurs d'argent en général. De plus, il est dans une mince couche et assez proche du rouge qui a déjà été identifié afin que vous puissiez suivre sa forme sur toute sa longueur pour calculer un pourcentage de ce qui peut être considéré comme l'anneau métallique de la boîte. Vraiment, vous n'avez besoin que d'une petite fraction de cette quantité pour pouvoir dire qu'elle en fait partie, mais vous devez tout de même trouver un équilibre pour vous assurer que ce n'est pas juste une bouteille vide avec du métal derrière.

Et enfin, le plus délicat. Mais pas si difficile, une fois que nous allons seulement par ce que nous pouvons voir directement au-dessus (et ci-dessous) l'emballage rouge. C'est transparent, ce qui signifie qu'il montrera tout ce qu'il y a derrière. C'est bien, parce que les choses qui sont derrière ne sont pas susceptibles d'être aussi cohérente en couleur que le métal circulaire argent de la boîte. Il pourrait y avoir beaucoup de choses différentes, qui nous diraient que c'est une bouteille vide (ou remplie de liquide clair), ou une couleur uniforme, ce qui pourrait signifier soit qu'elle est remplie de liquide ou que la bouteille est simplement devant un couleur unie. Nous travaillons avec ce qui se rapproche le plus du haut et du bas, et les chances que les bonnes couleurs soient au bon endroit sont relativement minces. Nous savons que c'est une bouteille, parce qu'elle n'a pas cet élément visuel clé de la boîte, ce qui est relativement simpliste par rapport à ce qui pourrait se trouver derrière une bouteille.

(ce dernier était le meilleur que je pouvais trouver d'une grande bouteille vide de coca-coca - intéressant le capuchon ET l'anneau sont jaunes, indiquant que la rougeur du chapeau ne devrait probablement pas être invoquée)

Dans la rare circonstance qu'une nuance d'argent similaire est derrière la bouteille, même après l'abstraction du plastique, ou que la bouteille est remplie d'une certaine manière de la même nuance de liquide d'argent, nous pouvons nous rabattre sur ce que nous pouvons estimer forme de l'argent - qui, comme je l'ai mentionné, est circulaire et suit la forme de la canette. Mais même si je manque de certaines connaissances en traitement d'image, cela semble lent. Mieux encore, pourquoi ne pas en déduire pour une fois vérifier les côtés du logo pour s'assurer qu'il n'y a rien de la même couleur d'argent là-bas? Ah, mais s'il y a la même nuance d'argent derrière une canette? Ensuite, nous devons en effet accorder plus d'attention aux formes, en regardant à nouveau le haut et le bas de la boîte.

En fonction de la perfection de tout cela, cela pourrait être très lent, mais je suppose que mon concept de base est de vérifier d'abord les choses les plus faciles et les plus proches. Aller par des différences de couleur autour de la forme déjà assortie (ce qui semble la partie la plus triviale de toute façon) avant d'aller à l'effort de travailler la forme des autres éléments. Pour le lister, ça va:

  • Trouver l'attraction principale (fond de logo rouge, et éventuellement le logo lui-même pour l'orientation, bien que dans le cas où la boîte est tournée, vous devez vous concentrer sur le rouge seul)
  • Vérifiez la forme et l'orientation, encore une fois via la rougeur très distinctive
  • Vérifiez les couleurs autour de la forme (car elle est rapide et indolore)
  • Enfin, si nécessaire, vérifiez la forme de ces couleurs autour de l'attraction principale pour la bonne circularité.

Dans le cas où vous ne pouvez pas faire cela, cela signifie probablement que le haut et le bas de la boîte sont couverts, et les seules choses possibles qu'un humain aurait pu utiliser pour faire une distinction fiable entre la canette et la bouteille est l'occlusion et la réflexion de la boîte, ce qui serait une bataille beaucoup plus difficile à traiter. Cependant, pour aller encore plus loin, vous pouvez suivre l'angle de la canette / bouteille pour vérifier d'autres traits ressemblant à des bouteilles, en utilisant les techniques de balayage semi-transparentes mentionnées dans les autres réponses.

Des cauchemars supplémentaires intéressants pourraient inclure une boîte placée à l'arrière de la bouteille à une distance telle que le métal se trouve juste au-dessus et au-dessous de l'étiquette, ce qui échouerait tant que vous balayez toute la longueur du rouge. étiquette - qui est en fait plus un problème parce que vous ne détectez pas une boîte où vous pourriez avoir, par opposition à considérer que vous êtes en train de détecter une bouteille, y compris la boîte par accident. Le verre est à moitié vide, dans ce cas!

En tant qu'exclusion, je n'ai aucune expérience et n'ai jamais pensé au traitement de l'image en dehors de cette question, mais c'est tellement intéressant que ça m'a fait réfléchir assez profondément, et après avoir lu toutes les autres réponses, je considère que c'est peut-être le moyen le plus simple et le plus efficace de le faire. Personnellement, je suis content de ne pas avoir à penser à la programmation!

MODIFIER

De plus, regardez ce dessin que j'ai fait dans MS Paint ... C'est absolument horrible et assez incomplet, mais basé sur la forme et les couleurs, vous pouvez deviner ce que ça va probablement être. En substance, ce sont les seules choses dont il faut se préoccuper. Quand vous regardez cette forme très distinctive et cette combinaison de couleurs si proches, qu'est-ce que cela pourrait bien être d'autre? Le bit que je n'ai pas peint, le fond blanc, devrait être considéré comme "quelque chose d'inconsistant". S'il avait un arrière-plan transparent, il pourrait passer sur presque toutes les autres images et vous pourriez toujours le voir.


Je ne suis pas au courant de OpenCV mais en regardant le problème logiquement, je pense que vous pourriez différencier entre la bouteille et la canette en changeant l'image que vous recherchez, par exemple Coca Cola. Vous devez incorporer jusqu'à la partie supérieure de la boîte comme dans le cas de la cannette il y a une doublure d'argent au sommet de la coca cola et dans le cas de la bouteille, il n'y aura pas une telle doublure d'argent.

Mais évidemment, cet algorithme échouera dans les cas où le sommet de la canette est caché, mais dans ce cas même l'humain ne sera pas en mesure de faire la différence entre les deux (si seulement la portion de coca-cola est visible)


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 ;-)


Les réponses sur cette page sont vraiment:

  • "utiliser SIFT"

  • "utiliser un Kinect"

Si vous n'êtes pas intéressé par l'informatique réelle de la reconnaissance d'image, et que vous voulez juste "utiliser" quelque chose (comme SIFT ou Kinect),

Il est aujourd'hui omniprésent d'utiliser simplement les systèmes de reconnaissance d'image couramment disponibles.

À partir de 2017 et depuis des années maintenant, la reconnaissance d'image est largement et trivialement disponible .

Vous ne vous asseyez pas et ne tentez pas d'obtenir une reconnaissance d'image à partir de zéro, vous vous contenteriez de rassembler et d'afficher des cartes ou de commencer à rendre HTML à partir de rien ou d'écrire une base de données SQL à partir de zéro.

Vous utilisez simplement le tensorflow de Google (ils ont atteint le point de construire des puces, pour l'amour de Dieu, pour traiter le flux tensoriel plus rapidement), Clarifai, Bluemix ou quoi que ce soit.

AWS vient de sortir un bon pour la reconnaissance d'image (2018).

Par exemple pour utiliser l'un de ces services c'est quelques lignes de code ....

func isItACokeCan() {

    jds.headers = ["Accept-Language":"en"]
    let h = JustOf<HTTP> ...use your favorite http library

    let u: String =
        "https://gateway-a.watsonplatform.net/visual-recognition/api/v3/classify"
        + "?api_key= ... your API key ..."
        + "&version=2016-05-20"
        + "&classifier_ids= ... your Classifier name ..."

    h.post( u,
        files: ["x.jpeg": .data("x.jpeg", liveImageData!, "image/jpeg")]

    ) { r in
        if r.ok { DispatchQueue.main.async { self.processResult(r.json) } }
        else { DispatchQueue.main.async { self.doResults("network woe?") } }
    }
}

func processResult(_ rr: Any?){
    let json = JSON(rr!)
    print("\(json)")
}

Cela vous donnera littéralement la meilleure, existante, la coke-can-reconnaissance sur Terre , actuellement réalisée.

En 2018, vous ne pouvez plus vous asseoir et "écrire une meilleure reconnaissance de coca-cola que Bluemix", que vous ne pourriez "vous asseoir et écrire un meilleur programme Go que AlphaGo".

Des systèmes tels que Siri, Google Maps, BAAS, les principaux efforts de traitement d'image - et évidemment la recherche de texte google elle-même - sont en train de changer la donne.

Notez la différence incroyable juste depuis que cette question a été posée il y a six ans.

Par tous les moyens, si vous êtes dans l'informatique réelle de la reconnaissance d'image , allez-y.

Mais ce QA semble être plus d'un examen de la technologie.

Dans la mesure où les réponses ici disent «utiliser une bibliothèque SIFT», vous ne le feriez vraiment pas. (Encore une fois - pas plus que vous pour une raison quelconque, programmez laborieusement un serveur web ou une base de données SQL à partir de zéro!)

Vous venez de vous connecter aux systèmes de reconnaissance d'images "BAAS" bien connus et omniprésents - c'est une ligne de code.


S'il vous plaît jeter un oeil à Predator tracker de Zdenek Kalal. 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 dans 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.


J'aime vraiment les réponses de Darren Cook et 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 les canettes de Coca-Cola des autres objets, y compris: bouteilles , panneaux d'affichage , publicités et accessoires Coca-Cola 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 can contient, ou, à travers l'espace négatif, quelles caractéristiques sont présentes pour les autres produits de Coke qui ne sont pas présents pour les canettes. À cette fin, la première 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, ce 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:

  • La forme de la silhouette de l'objet, telle que vous l'avez esquissée dans votre question , est-elle correcte? 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.
  • Déterminons-nous que les propriétés spéculaires de l'objet sont correctes, par rapport à nos sources lumineuses ( lien vidéo illustratif sur la 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é temporelle et spatiale très différente, et pour chaque approche, un passage rapide sur 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 un peut invalider 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 pour l'article de Hacker News! Dans l'ensemble, c'est une très bonne question digne de la publicité qu'elle a reçue. :)


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".

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 la bouteille, je chercherais du coke (le liquide brun) adjacent au logo, c'est-à-dire à l' intérieur de la bouteille ou, dans le cas d'une bouteille vide, je chercherais un bonnet qui La même forme de base, la même taille et la même distance que le logo seront généralement blanches ou rouges.Recherchez une forme elliptique de couleur unie où un chapeau devrait être, par rapport au logo.Non infaillible bien sûr, mais votre but ici devrait être de trouver les faciles facilement .)

(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!)


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.-à-d. 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 l' stereo-imaging , puis récupérer la taille d'origine.


Si vous n'êtes pas limité à une caméra qui n'était pas dans l'une de vos contraintes, vous pouvez peut-être 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.


Comme alternative à toutes ces belles solutions, vous pouvez former votre propre classificateur et rendre votre application robuste aux erreurs. Par exemple, vous pouvez utiliser Haar Training , fournissant un bon nombre d'images positives et négatives de votre cible.

Il peut être utile d'extraire uniquement des boîtes et peut être combiné avec la détection d'objets transparents.


Il existe un package de vision par ordinateur appelé HALCON de MVTec dont les démos pourraient vous donner de bonnes idées d'algorithme. Il y a beaucoup d'exemples similaires à votre problème que vous pourriez exécuter en mode démo et ensuite regarder les opérateurs dans le code et voir comment les implémenter à partir d'opérateurs OpenCV existants.

J'ai utilisé ce paquet pour prototyper rapidement des algorithmes complexes pour des problèmes comme celui-ci et ensuite trouver comment les implémenter en utilisant les fonctionnalités OpenCV existantes. En particulier pour votre cas, vous pouvez essayer d'implémenter dans OpenCV la fonctionnalité intégrée dans l'opérateur find_scaled_shape_model . Certains opérateurs pointent vers le document scientifique concernant la mise en œuvre de l'algorithme qui peut aider à trouver comment faire quelque chose de similaire dans OpenCV. J'espère que cela t'aides...


If you are interested in it being realtime, then what you need is to add in a pre-processing filter to determine what gets scanned with the heavy-duty stuff. A good fast, very real time, pre-processing filter that will allow you to scan things that are more likely to be a coca-cola can than not before moving onto more iffy things is something like this: search the image for the biggest patches of color that are a certain tolerance away from the sqrt(pow(red,2) + pow(blue,2) + pow(green,2)) of your coca-cola can. Start with a very strict color tolerance, and work your way down to more lenient color tolerances. Then, when your robot runs out of an allotted time to process the current frame, it uses the currently found bottles for your purposes. Please note that you will have to tweak the RGB colors in the sqrt(pow(red,2) + pow(blue,2) + pow(green,2)) to get them just right.

Also, this is gona seem really dumb, but did you make sure to turn on -oFast compiler optimizations when you compiled your C code?


L'apprentissage en profondeur

Rassemblez au moins quelques centaines d'images contenant des boîtes de cola, annotez le cadre entourant autour d'elles comme des classes positives, incluez des bouteilles de cola et d'autres produits à base de cola et étiquetez-les comme des classes négatives ainsi que des objets aléatoires.

Sauf si vous collectez un ensemble de données très volumineux, essayez d'utiliser des fonctionnalités d'apprentissage en profondeur pour les petits ensembles de données. Idéalement, utiliser une combinaison de machines à vecteurs de support (SVM) avec des réseaux neuronaux profonds.

Une fois que vous avez injecté les images dans un modèle d'apprentissage en profondeur (par exemple GoogleNet), au lieu d'utiliser la couche de décision (finale) du réseau de neurones pour effectuer les classifications, utilisez les données des couches précédentes pour former votre classificateur.

OpenCV et Google Net: http://docs.opencv.org/trunk/d5/de7/tutorial_dnn_googlenet.html

OpenCV et SVM: http://docs.opencv.org/2.4/doc/tutorials/ml/introduction_to_svm/introduction_to_svm.html


Maybe too many years late, but nevertheless a theory to try.

The ratio of bounding rectangle of red logo region to the overall dimension of the bottle/can is different. In the case of Can, should be 1:1, whereas will be different in that of bottle (with or without cap). This should make it easy to distinguish between the two.

Update: The horizontal curvature of the logo region will be different between the Can and Bottle due their respective size difference. This could be specifically useful if your robot needs to pick up can/bottle, and you decide the grip accordingly.


Il y a un tas de descripteurs de couleur utilisés pour reconnaître les objets, le papier ci-dessous compare beaucoup d'entre eux. Ils sont particulièrement puissants lorsqu'ils sont combinés avec SIFT ou SURF. SURF ou SIFT seul ne sont pas très utiles dans une image de coca-cola parce qu'ils ne reconnaissent pas beaucoup de points d'intérêt, vous avez besoin de l'information de couleur pour vous aider. J'utilise BIC (Classi fi cation de pixels de bord / intérieur) avec SURF dans un projet et cela fonctionne très bien pour reconnaître des objets.

Descripteurs de couleurs pour la récupération d'images Web: une étude comparative


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.





opencv