J'aimerais prendre des photos d'étiquettes sur un pot d'aliments et pouvoir les transformer de manière à ce que l'étiquette soit plate, le côté droit et le côté gauche étant redimensionnés de manière à être au même niveau que le centre de l'image.
Idéalement, j'aimerais utiliser le contraste entre l'étiquette et l'arrière-plan pour trouver les bords et appliquer la correction. Sinon, je peux demander à l'utilisateur d'identifier en quelque sorte les coins et les côtés de l'image.
Je recherche des techniques générales et des algorithmes pour prendre une image asymétrique sphérique (cylindrique dans mon cas) et pouvant aplatir l'image. Actuellement, l'image d'une étiquette qui est enroulée autour d'un pot ou d'une bouteille aura des caractéristiques et du texte qui se contracte à mesure qu'elle se rétracte à droite ou à gauche de l'image. De plus, les lignes qui désignent le bord de l'étiquette ne seront que parallèles au centre de l'image et seront inclinées l'une vers l'autre à l'extrême droite et à l'extrême gauche de l'étiquette.
Après avoir manipulé l'image, j'aimerais disposer d'un rectangle presque parfait où le texte et les éléments sont de taille uniforme, comme si j'avais pris une photo de l'étiquette alors qu'elle n'était ni sur le pot ni sur la bouteille.
Aussi, j'aimerais que la technique détecte automatiquement les bords de l'étiquette, afin d'appliquer la correction appropriée. Sinon, je devrais demander à mon utilisateur d'indiquer les limites de l'étiquette.
J'ai déjà googlé et trouvé des articles comme celui-ci: aplatir les documents incurvés , mais je cherche quelque chose d'un peu plus simple, car j'ai besoin d'utiliser des étiquettes avec une simple courbe.
la source
Réponses:
Une question similaire a été posée sur Mathematica.Stackexchange . Ma réponse a évolué et a été assez longue à la fin, donc je vais résumer l’algorithme ici.
Abstrait
L'idée de base est:
L'algorithme ne fonctionne que pour les images où:
Cependant, l'algorithme est modulaire. Au moins en principe, vous pouvez écrire votre propre détection d’étiquette qui ne nécessite pas d’arrière-plan sombre ou votre propre fonction de mesure de la qualité, compatible avec les étiquettes elliptiques ou octogonales.
Résultats
Ces images ont été traitées de manière entièrement automatique, c’est-à-dire que l’algorithme prend l’image source, fonctionne pendant quelques secondes, puis affiche le mappage (à gauche) et l’image non déformée (à droite):
Les images suivantes ont été traitées avec une version modifiée de l’algorithme, si l’utilisateur sélectionne les bords gauche et droit du pot (et non l’étiquette), car la courbure de l’étiquette ne peut pas être estimée à partir de l’image dans un plan frontal (c.-à-d. Le algorithme entièrement automatique renvoie des images légèrement déformées):
La mise en oeuvre:
1. Trouver l'étiquette
L'étiquette est brillante devant un fond sombre, je peux donc la trouver facilement en utilisant la binarisation:
Je choisis simplement le plus grand composant connecté et suppose que c'est l'étiquette:
2. Trouver les bordures de l'étiquette
Étape suivante: recherchez les bordures haut / bas / gauche / droite à l’aide de simples masques de convolution dérivés:
Il s’agit d’une petite fonction d’aide qui trouve tous les pixels blancs dans l’une de ces quatre images et convertit les index en coordonnées (
Position
renvoie les index et les index sont des {{, x} -tuples basés sur 1, où y = 1 est au sommet de l’image, mais toutes les fonctions de traitement de l’image attendent des coordonnées, qui sont des {x, y} -tuples basés sur 0, où y = 0 est le bas de l’image):3. Trouver une correspondance entre les coordonnées de l’image et les coordonnées du cylindre
Maintenant, j'ai quatre listes distinctes de coordonnées des bordures supérieure, inférieure, gauche et droite de l'étiquette. Je définis une correspondance entre les coordonnées de l'image et les coordonnées du cylindre:
Il s'agit d'une application cylindrique, qui mappe les coordonnées X / Y de l'image source en coordonnées cylindriques. La cartographie présente 10 degrés de liberté hauteur / rayon / centre / perspective / inclinaison. J'ai utilisé la série de Taylor pour approximer l'arc sinus, car je ne pouvais pas utiliser l'optimisation directement avec ArcSin. le
Clip
les appels sont ma tentative ad hoc d’empêcher les nombres complexes lors de l’optimisation. Il y a un compromis à faire ici: d'une part, la fonction doit être aussi proche que possible d'une représentation cylindrique exacte, afin de produire la distorsion la plus faible possible. D'autre part, si c'est trop compliqué, il devient beaucoup plus difficile de trouver automatiquement des valeurs optimales pour les degrés de liberté. (Ce qui est bien avec le traitement des images avec Mathematica, c’est que vous pouvez manipuler des modèles mathématiques comme celui-ci très facilement, introduire des termes supplémentaires pour différentes distorsions et utiliser les mêmes fonctions d’optimisation pour obtenir des résultats finaux. Je n’ai jamais rien pu faire. comme cela avec OpenCV ou Matlab. Mais je n’ai jamais essayé la boîte à outils symbolique pour Matlab, c’est peut-être plus utile.)Ensuite, je définis une "fonction d'erreur" qui mesure la qualité d'une représentation image -> cylindre. C'est juste la somme des erreurs au carré pour les pixels de bordure:
Cette fonction d'erreur mesure la "qualité" d'un mappage: sa valeur la plus basse si les points du bord gauche sont mappés sur (0 / [rien]), les pixels du bord supérieur sont mappés sur ([rien] / 0), etc. .
Je peux maintenant dire à Mathematica de trouver des coefficients qui minimisent cette fonction d'erreur. Je peux faire des "suppositions éclairées" sur certains des coefficients (par exemple, le rayon et le centre du pot dans l'image). Je les utilise comme points de départ de l'optimisation:
FindMinimum
trouve des valeurs pour les 10 degrés de liberté de ma fonction de mappage qui minimisent la fonction d'erreur. Combinez le mappage générique et cette solution et vous obtenez un mappage à partir des coordonnées d'image X / Y, qui correspond à la zone d'étiquette. Je peux visualiser cette cartographie en utilisant laContourPlot
fonction de Mathematica :4. Transformer l'image
Enfin, j'utilise la
ImageForwardTransform
fonction Mathematica pour déformer l'image en fonction de ce mappage:Cela donne les résultats comme indiqué ci-dessus.
Version assistée manuellement
L'algorithme ci-dessus est complètement automatique. Aucun ajustement requis. Cela fonctionne raisonnablement bien tant que la photo est prise d'en haut ou en bas. Mais s'il s'agit d'un tir frontal, le rayon du pot ne peut pas être estimé à partir de la forme de l'étiquette. Dans ces cas, j'obtiens de bien meilleurs résultats si je laisse l'utilisateur entrer manuellement les bordures gauche / droite du pot et définir explicitement les degrés de liberté correspondants dans le mappage.
Ce code permet à l'utilisateur de sélectionner les bordures gauche / droite:
C'est le code d'optimisation alternatif, où le centre et le rayon sont donnés explicitement.
la source