web-dev-qa-db-fra.com

Comment trouver Wally avec Python?

Sauter sans vergogne dans le train en marche :-)

Inspiré par Comment trouver Waldo avec Mathematica et le suivi Comment trouver Waldo avec R , en tant que nouvel utilisateur python utilisateur J'adore voir comment cela pourrait être fait. Il semble que python serait mieux adapté à cela que R, et nous n'avons pas à nous soucier des licences comme nous le ferions avec Mathematica ou Matlab.

Dans un exemple comme celui ci-dessous, le simple fait d'utiliser des rayures ne fonctionnerait évidemment pas. Il serait intéressant qu'une approche simple basée sur des règles puisse être mise en œuvre pour des exemples difficiles comme celui-ci.

At the beach

J'ai ajouté la balise [machine-learning] car je pense que la bonne réponse devra utiliser des techniques de ML, telles que l'approche RBM (Restricted Boltzmann Machine) préconisée par Gregory Klopper dans le fil d'origine. Il y a le code RBM est disponible en python qui pourrait être un bon point de départ, mais des données de formation sont évidemment nécessaires pour cette approche.

Lors du Atelier international IEEE 2009 sur L'APPRENTISSAGE DES MACHINES POUR LE TRAITEMENT DES SIGNAUX (MLSP 2009) ils ont organisé un Concours d'analyse de données: Où est Wally? . Les données de formation sont fournies au format matlab. Notez que les liens sur ce site sont morts, mais les données (ainsi que la source d'une approche adoptée par Sean McLoone et ses collègues peuvent être trouvées ici (voir lien SCM) Semble être un point de départ.

82
tdc

Voici une implémentation avec mahotas

from pylab import imshow
import numpy as np
import mahotas
wally = mahotas.imread('DepartmentStore.jpg')

wfloat = wally.astype(float)
r,g,b = wfloat.transpose((2,0,1))

Divisez en canaux rouge, vert et bleu. Il est préférable d'utiliser l'arithmétique à virgule flottante ci-dessous, nous convertissons donc en haut.

w = wfloat.mean(2)

w est le canal blanc.

pattern = np.ones((24,16), float)
for i in xrange(2):
    pattern[i::4] = -1

Construisez un motif de + 1, + 1, -1, -1 sur l'axe vertical. Ceci est la chemise de Wally.

v = mahotas.convolve(r-w, pattern)

Convolve avec du rouge moins blanc. Cela donnera une réponse forte où se trouve la chemise.

mask = (v == v.max())
mask = mahotas.dilate(mask, np.ones((48,24)))

Recherchez la valeur maximale et dilatez-la pour la rendre visible. Maintenant, nous atténuons l'image entière, sauf la région ou l'intérêt:

wally -= .8*wally * ~mask[:,:,None]
imshow(wally)

Et nous obtenons waldo!

62
luispedro

Vous pouvez essayer la correspondance de modèles, puis supprimer ce qui produit la ressemblance la plus élevée, puis utiliser l'apprentissage automatique pour affiner davantage. C'est également très difficile, et avec la précision de la correspondance des modèles, cela peut simplement renvoyer chaque visage ou image semblable à un visage. Je pense que vous aurez besoin de plus que du simple apprentissage automatique si vous espérez le faire de manière cohérente.

2
a sandwhich

vous devriez peut-être commencer par diviser le problème en deux plus petits:

  1. créer un algorithme qui sépare les gens de l'arrière-plan.
  2. former un classificateur de réseau neuronal avec autant d'exemples positifs et négatifs que possible.

ce sont encore deux très gros problèmes à résoudre ...

BTW, je choisirais c ++ et ouvrir CV, cela semble beaucoup plus adapté à cela.

2
WeaselFox

Ce n'est pas impossible mais très difficile car vous n'avez vraiment aucun exemple de match réussi. Il y a souvent plusieurs états (dans ce cas, plus d'exemples de dessins de recherche de walleys), vous pouvez ensuite alimenter plusieurs images dans un programme de reconstitution d'image et le traiter comme un modèle markov caché et utiliser quelque chose comme l'algorithme viterbi pour l'inférence ( http://en.wikipedia.org/wiki/Viterbi_algorithm ).

C'est la façon dont je l'aborderais, mais en supposant que vous avez plusieurs images, vous pouvez lui donner des exemples de la bonne réponse pour qu'il puisse apprendre. Si vous n'avez qu'une seule photo, je suis désolé, il y a peut-être une autre approche que vous devez adopter.

1
Lostsoul

Voici une solution en utilisant des réseaux de neurones qui fonctionnent bien.

Le réseau de neurones est formé sur plusieurs exemples résolus qui sont marqués par des cadres de délimitation indiquant où Wally apparaît dans l'image. Le but du réseau est de minimiser l'erreur entre la boîte prédite et la boîte réelle à partir des données de formation/validation.

Le réseau ci-dessus utilise l'API de détection d'objets Tensorflow pour effectuer des formations et des prévisions.

1
Tadej Magajna

J'ai reconnu qu'il y a deux caractéristiques principales qui sont presque toujours visibles:

  1. la chemise rayée rouge-blanc
  2. cheveux brun foncé sous le bonnet fantaisie

Je le ferais donc de la manière suivante:

recherche de chemises rayées:

  • filtrer les couleurs rouge et blanc (avec des seuils sur l'image convertie HSV). Cela vous donne deux images de masque.
  • ajoutez-les ensemble -> c'est le masque principal pour rechercher des chemises à rayures.
  • créer une nouvelle image avec tout le rouge filtré converti en rouge pur (# FF0000) et tout le blanc filtré converti en blanc pur (#FFFFFF).
  • corrélons maintenant cette image rouge-blanc pur avec une image de motif de rayures (je pense que tous les waldo ont des rayures horizontales assez parfaites, donc la rotation du motif ne devrait pas être nécessaire). Faites la corrélation uniquement à l'intérieur du masque principal mentionné ci-dessus.
  • essayez de regrouper les clusters qui auraient pu être le résultat de une chemise.

S'il y a plus d'une "chemise", c'est-à-dire plus d'une grappe de corrélation positive, recherchez d'autres caractéristiques, comme les cheveux brun foncé:

recherche de cheveux bruns

  • filtrer la couleur spécifique des cheveux bruns en utilisant l'image convertie en HSV et certains seuils.
  • recherchez une certaine zone dans cette image masquée - ni trop grande ni trop petite.
  • recherchez maintenant une "zone de cheveux" qui est juste au-dessus d'une chemise rayée détectée (avant) et qui a une certaine distance par rapport au centre de la chemise.
1
Cyril