web-dev-qa-db-fra.com

Comment trouver Waldo avec Mathematica?

Cela me dérangeait ce week-end: Quel est le bon moyen de résoudre ces Où est Waldo? [ 'Wally' en dehors de l'Amérique du Nord], en utilisant Mathematica (traitement d'image et autres fonctionnalités)?

Voici ce que j'ai jusqu'à présent, une fonction qui réduit un peu la complexité visuelle en atténuant certaines des couleurs non rouges:

whereIsWaldo[url_] := Module[{waldo, waldo2, waldoMask},
    waldo = Import[url];
    waldo2 = Image[ImageData[
        waldo] /. {{r_, g_, b_} /;
          Not[r > .7 && g < .3 && b < .3] :> {0, 0,
          0}, {r_, g_, b_} /; (r > .7 && g < .3 && b < .3) :> {1, 1,
          1}}];
    waldoMask = Closing[waldo2, 4];
    ImageCompose[waldo, {waldoMask, .5}]
]

Et un exemple d'URL où cela 'fonctionne':

whereIsWaldo["http://www.findwaldo.com/fankit/graphics/IntlManOfLiterature/Scenes/DepartmentStore.jpg"]

(Waldo est à la caisse):

Mathematica graphic

1537
Arnoud Buzing

J'ai trouvé Waldo!

waldo had been found

comment je l'ai fait

Tout d'abord, je filtre toutes les couleurs qui ne sont pas rouges

waldo = Import["http://www.findwaldo.com/fankit/graphics/IntlManOfLiterature/Scenes/DepartmentStore.jpg"];
red = Fold[ImageSubtract, #[[1]], Rest[#]] &@ColorSeparate[waldo];

Ensuite, je calcule la corrélation de cette image avec un simple motif noir et blanc pour trouver les transitions rouge et blanc dans la chemise.

corr = ImageCorrelate[red, 
   Image@Join[ConstantArray[1, {2, 4}], ConstantArray[0, {2, 4}]], 
   NormalizedSquaredEuclideanDistance];

J'utilise Binarize pour sélectionner les pixels de l'image avec une corrélation suffisamment élevée et trace un cercle blanc autour d'eux pour les accentuer à l'aide de Dilation

pos = Dilation[ColorNegate[Binarize[corr, .12]], DiskMatrix[30]];

Je devais jouer un peu avec le niveau. Si le niveau est trop élevé, trop de faux positifs sont sélectionnés.

Enfin, je combine ce résultat avec l'image d'origine pour obtenir le résultat ci-dessus

found = ImageMultiply[waldo, ImageAdd[ColorConvert[pos, "GrayLevel"], .5]]
1635
Heike

À mon avis, il s'agit d'un "moyen infaillible de faire cela" (pensez à la CIA de trouver Waldo dans n'importe quelle image satellite à tout moment, pas seulement une image sans éléments concurrents, comme des chemises à rayures) ... Je formerais un machine Boltzmann sur de nombreuses images de Waldo - toutes les variations de lui assis, debout, occlus, etc. chemise, chapeau, appareil photo et toutes les œuvres. Vous n'avez pas besoin d'un grand corpus de Waldos (peut-être que 3 à 5 suffiront), mais plus il y en a, mieux c'est.

Cela affectera des nuées de probabilités à divers éléments apparaissant dans la bonne disposition, puis établira (via la segmentation) ce qu'est une taille d'objet moyenne, fragmentera l'image source en cellules d'objets qui ressemblent le plus à des personnes (en tenant compte des occlusions possibles et des changements de pose). ), mais comme les images de Waldo incluent généralement BEAUCOUP de personnes à peu près à la même échelle, la tâche devrait être très facile, puis alimentez ces segments de la machine Boltzmann pré-formée. Cela vous donnera la probabilité que chacun soit Waldo. Prenez-en un avec la probabilité la plus élevée.

C’est ainsi que fonctionnent l’OCR, les lecteurs de code postal et la reconnaissance de l’écriture manuscrite sans trait. Fondamentalement, vous savez que la réponse est là, vous savez plus ou moins à quoi cela devrait ressembler, et tout le reste peut avoir des éléments communs, mais est définitivement "pas ça", de sorte que vous ne vous occupez pas des "pas ça", vous Il suffit de regarder la probabilité de "ça" parmi tous les "ce que vous avez vu auparavant" (dans des codes postaux par exemple, vous entraînerez un BM pour seulement 1s, seulement 2s, seulement 3s, etc., puis nourrissez chaque chiffre sur chaque machine et choisissez-en une qui a le plus de confiance), ce qui fonctionne beaucoup mieux qu'un réseau de neurones unique offrant des fonctionnalités d'apprentissage de tous les nombres.

143
Gregory Klopper

Je suis d'accord avec @GregoryKlopper sur le fait que le moyen correct de résoudre le problème général de trouver Waldo (ou tout objet d'intérêt) dans une image arbitraire serait de former un classificateur d'apprentissage automatique supervisé. En utilisant de nombreux exemples étiquetés positifs et négatifs, un algorithme tel que Support Vector Machine , Boosted Decision Stump ou Boltzmann Machine pourrait probablement être formé pour obtenir une haute précision sur ce problème. Mathematica inclut même ces algorithmes dans son Machine Learning Framework .

La formation d’un classifieur Waldo comporterait deux défis:

  1. Détermination de la bonne transformation de l'image. C'est là que la réponse de @ Heike serait utile: un filtre rouge et un détecteur de motif rayé (décomposition en ondelettes ou DCT, par exemple) seraient un bon moyen de transformer les pixels bruts en un format que l'algorithme de classification pourrait apprendre. Une décomposition par blocs évaluant toutes les sous-sections de l'image serait également nécessaire ... mais cela est facilité par le fait que Waldo est a) toujours à peu près de la même taille et b) toujours présent exactement une fois dans chaque image.
  2. Obtenir suffisamment d'exemples de formation. Les SVM fonctionnent mieux avec au moins 100 exemples de chaque classe. Les applications commerciales de boosting (par exemple, la mise au point de visages dans des appareils photo numériques) sont formées à des millions d'exemples positifs et négatifs.

Un rapide recherche d'image Google fournit de bonnes données - je vais essayer de rassembler des exemples de formation et de les coder immédiatement!

Cependant, même une approche d'apprentissage automatique (ou l'approche basée sur des règles suggérée par @iND) luttera pour une image telle que le Land of Waldos !

46
lubar

Je ne connais pas Mathematica. . . dommage. Mais j'aime la réponse ci-dessus, pour la plupart.

Il y a tout de même un défaut majeur à compter sur les bandes seules pour glaner la réponse (personnellement, je n'ai pas de problème avec un ajustement manuel). Il y a un exemple (cité par Brett Champion, ici ) présenté qui montre qu'ils rompent parfois le motif de la chemise. Alors, cela devient un motif plus complexe.

Je voudrais essayer une approche de la forme et des couleurs, ainsi que des relations spatiales. Tout comme la reconnaissance des visages, vous pouvez rechercher des motifs géométriques à certains ratios les uns des autres. La mise en garde est que généralement une ou plusieurs de ces formes est occlus.

Obtenez une balance des blancs sur l'image et rouge une balance rouge à partir de l'image. Je crois que Waldo a toujours la même valeur/teinte, mais l'image peut provenir d'un scan ou d'une mauvaise copie. Ensuite, faites toujours référence à un éventail de couleurs que Waldo est en réalité: rouge, blanc, marron foncé, bleu, pêche, {couleur de la chaussure}.

Il existe un motif de chemise, ainsi que le pantalon, les lunettes, les cheveux, le visage, les chaussures et le chapeau qui définissent Waldo. En outre, par rapport aux autres personnes de l'image, Waldo est plutôt maigre.

Alors, trouvez des personnes aléatoires pour obtenir la taille de personnes sur cette photo. Mesurez la hauteur moyenne d’un tas de choses à des points aléatoires de l’image (un simple contour permet de générer un certain nombre de personnes). Si chaque élément ne correspond pas à un écart type, il est ignoré pour le moment. Comparez la moyenne des hauteurs à la hauteur de l'image. Si le rapport est trop élevé (par exemple, 1: 2, 1: 4 ou similaire), essayez à nouveau. Exécutez-le 10 (?) Fois pour vous assurer que les échantillons sont tous assez proches les uns des autres, à l'exclusion de toute moyenne en dehors d'un écart-type. Possible dans Mathematica?

Ceci est votre taille Waldo. Walso est maigre, vous cherchez donc quelque chose 5: 1 ou 6: 1 (ou autre) ht: wd. Cependant, cela ne suffit pas. Si Waldo est partiellement caché, la hauteur pourrait changer. Vous cherchez donc un bloc de rouge-blanc qui ~ 2: 1. Mais il doit y avoir plus d'indicateurs.

  1. Waldo a des lunettes. Recherchez deux cercles 0.5: 1 au-dessus du rouge-blanc.
  2. Pantalon bleu. Toute quantité de bleu à la même largeur sur toute distance entre la fin du rouge-blanc et la distance à ses pieds. Notez qu'il porte sa chemise courte, donc les pieds ne sont pas trop proches.
  3. Le chapeau. Blanc-rouge n’importe quelle distance jusqu’à deux fois le haut de sa tête. Notez qu'il doit avoir les cheveux noirs en dessous et probablement des lunettes.
  4. Manches longues. rouge-blanc à un certain angle de la principale rouge-blanc.
  5. Cheveux foncés.
  6. Couleur de la chaussure Je ne connais pas la couleur.

N'importe lequel de ceux-ci pourrait s'appliquer. Ce sont aussi des chèques négatifs contre des personnes similaires sur la photo - par exemple, le n ° 2 empêche de porter un tablier rouge-blanc (trop près des chaussures), le n ° 5 élimine les cheveux clairs. De plus, la forme n'est qu'un indicateur pour chacun de ces tests. . . la couleur seule dans la distance spécifiée peut donner de bons résultats.

Cela permettra de réduire les domaines à traiter.

Le stockage de ces résultats produira un ensemble de zones dans lesquelles devrait contenir Waldo. Excluez tous les autres domaines (par exemple, pour chaque domaine, sélectionnez un cercle deux fois plus grand que la taille moyenne d'une personne), puis exécutez le processus que @Heike a défini en supprimant tout sauf le rouge, etc.

Des idées sur la façon de coder cela?


Modifier:

Réflexions sur la manière de coder ceci. . . exclure toutes les zones sauf le rouge Waldo, squelettiser les zones rouges et les tailler en un seul point. Faites de même pour les cheveux Waldo bruns, les pantalons Waldo bleus, les chaussures Waldo. Pour la couleur de peau Waldo, excluez, puis recherchez le contour.

Ensuite, excluez les non-rouges, dilatez (beaucoup) toutes les zones rouges, puis squelettisez et élaguez. Cette partie donnera une liste des points centraux Waldo possibles. Ce sera le marqueur auquel comparer toutes les autres sections de couleur Waldo.

À partir de là, en utilisant les zones rouges squelettisées (et non les dilatées), comptez les lignes de chaque zone. S'il y a le bon numéro (quatre, n'est-ce pas?), C'est certainement un domaine possible. Si ce n’est pas le cas, je suppose que l’exclure (en tant que centre de Waldo... Peut-être encore son chapeau).

Ensuite, vérifiez s'il y a une forme de visage au-dessus, une pointe de poil au-dessus, une pointe de pantalon en dessous, une pointe de chaussure en dessous, etc.

Pas encore de code - toujours en train de lire la documentation.

40
iND

J'ai une solution rapide pour trouver Waldo en utilisant OpenCV.

J'ai utilisé la fonction de correspondance de modèles disponible dans OpenCV pour trouver Waldo.

Pour ce faire, un modèle est nécessaire. J'ai donc recadré Waldo à partir de l'image d'origine et je l'ai utilisé comme modèle.

enter image description here

Ensuite, j'ai appelé la fonction cv2.matchTemplate() avec le coefficient de corrélation normalisé comme méthode utilisée. Il a renvoyé une probabilité élevée dans une seule région, comme indiqué en blanc ci-dessous (quelque part dans la région supérieure gauche):

enter image description here

La position de la région probable la plus élevée a été trouvée à l'aide de la fonction cv2.minMaxLoc(), que j'ai ensuite utilisée pour dessiner le rectangle afin de mettre en évidence Waldo:

enter image description here

2
Jeru Luke