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.
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) :
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 :
- 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.
- 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.
- 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.
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 :
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 ?
7 votes
@stacker marque un bon point. Pour la vitesse, vous voulez obtenir des caractéristiques peu coûteuses à calculer, comme les histogrammes de gradients orientés. Une première approche vraiment naïve consisterait à étiqueter manuellement un ensemble de rectangles de boîtes de conserve dans certaines images d'entraînement, et à utiliser ces rectangles ainsi que des exemples négatifs aléatoires pour entraîner un classificateur SVM ou un arbre de décision. L'apprentissage sera plus long, mais l'exécution sur de nouvelles images sera beaucoup plus rapide. J'ai l'intention d'écrire cette méthode quand j'aurai plus de temps libre pour inclure les bonnes références.
0 votes
@stacker J'ai fait cela parce que la portée de la mission visait spécifiquement les canettes de Coca-Cola. Je ne connais pas grand-chose à SIFT ou SURF, mais si cet algorithme convient à ce problème, j'aimerais beaucoup voir une réponse à ce sujet.
9 votes
Que diriez-vous d'une approche similaire à reCAPTCHA ? ;)
39 votes
Pourquoi cela a-t-il été déplacé de dsp.stackexchange.com ? Il semble que ce site serait encore mieux adapté que stackoverflow o_O
0 votes
@GeorgeDuckett reCAPTCHA pourrait être une idée, mais vous n'avez absolument aucune garantie que les lettres Coca-Cola seront visibles, elles pourraient être totalement cachées, partiellement cachées, ou la canette pourrait être retournée. Et ça ne résout pas non plus le problème avec la bouteille puisque les lettres sont les mêmes.
2 votes
Avez-vous essayé de détecter le joint supérieur ou inférieur de la boîte ? Il pourrait être possible de le détecter comme un bord parallèle au bord de la zone rouge.
0 votes
Je ne voulais pas dire pour la reconnaissance de caractères, je voulais dire utiliser l'idée d'utiliser des humains pour faire la recherche. Par exemple, montrer deux images, une connue et une inconnue. Je plaisantais. :-)
0 votes
Pouvez-vous ajouter quelques images de test supplémentaires pour vous faire une idée plus précise ?
0 votes
Avez-vous essayé sans convertir RGB en HSV ? Je pense que votre problème de bouteilles se trouve dans votre conversion, en fait vous avez supprimé vos boîtes de conserve dans votre première étape.
0 votes
@SaeedAmiri Non, la conversion en HSV fonctionne bien, c'est juste pour que je puisse éliminer certains des éléments qui ne ressemblent clairement pas à du rouge. La canette et la bouteille sont toujours là même après le passage en HSV, le problème est surtout de savoir comment différencier les 2 puisqu'elles ont des caractéristiques communes.
0 votes
Mais il semble que votre échantillon dise autre chose, je pense que dans votre premier échantillon, après le prétraitement, les images de la boîte peuvent être supprimées ? pouvez-vous organiser vos échantillons étape par étape ?
0 votes
@SaeedAmiri Oh je vois ce que vous voulez dire, les images 2 et 3 de ma question ne sont pas du même original ! Dans l'image 3, il n'y avait qu'une boîte de conserve. J'aurais pu en poster plus, mais j'essaie de garder la question au strict minimum. Supposez simplement que la traduction HSV conserve correctement la boîte et les bouteilles (+ un peu de bruit sur toute l'image).
0 votes
J'ai une grande attirance pour ce type de logiciel. Quelqu'un sait-il s'il existe une bibliothèque Java mature et bien établie pour faire ces reconnaissances d'images ?
2 votes
@EdPichler openCV a très récemment publié ses bindings java pour sa bibliothèque (à partir de 2.4.4). Donc, en gros, vous pouvez utiliser openCV en java (sans tout le tracas de faire JNI manuellement). J'ai essayé et cela a bien fonctionné (mais c'est encore bogué puisque c'est très récent).
0 votes
Tout ça me dépasse, mais je me disais : "pourquoi ne pas utiliser le module GPU d'OpenCV et profiter de votre GPU pour l'accélérer de façon spectaculaire ?" OpenCV dispose d'un module GPU qui contient des algorithmes comme les transformations de Hough et autres, écrits en CUDA et exécutés sur des GPU compatibles avec CUDA. Ce qui est génial ici, c'est qu'il n'est pas nécessaire d'apprendre CUDA. Il suffit d'importer le module gpu et de commencer à l'utiliser. J'espère que cela vous aidera (cela devrait théoriquement augmenter les performances d'un ordre de grandeur ou plus).
0 votes
Cela ressemble à une application évidente d'un réseau neuronal convolutionnel avec invariance d'échelle/de rotation.
0 votes
Si vous utilisez une hough-transform, vous devez utiliser une version plus rapide de l'algorithme original. Vous pouvez modifier la hough-transform pour vous concentrer uniquement sur les paramètres à haute probabilité en utilisant des méthodes comme RANSAC.
0 votes
Seule l'information du rouge et du blanc spéciaux dans le coca-cola est suffisamment distincte.
0 votes
C'est sans conteste l'un des projets les plus cool que j'ai vu quelqu'un entreprendre sur StackOverflow.
3 votes
1337 ! S'il vous plaît, personne ne upvote cette question à nouveau
4 votes
C'est une pub pour Coca-Cola ?
1 votes
Cette question doit être fermée pour 5 ou 6 raisons différentes, veuillez cliquer sur le bouton "Fermer".
3 votes
La vraie question est de savoir si la can can can can can
0 votes
@CharlesMenguy j'ai vraiment besoin d'aide avec cette question, pouvez-vous m'aider, s'il vous plaît ? stackoverflow.com/questions/61216402/
1 votes
Je me demande comment cette tâche serait gérée en 2020 avec des CNN en folie. Il existe des choses du type SSD/YOLO/Unet, mais elles concernent principalement des objets de grande taille. Je me demande s'il existe un équivalent pour les petits objets de tous les jours comme les montres, les téléphones, les jouets, etc.
0 votes
@GeorgeDuckett le temps de traitement par image serait assez long pour cette approche ;)