with pyimagesearch practical open learning learn for computer and python image-processing machine-learning computer-vision

pyimagesearch - ¿Cómo encuentro a Wally con Python?



practical python and opencv (6)

Desvergonzadamente subiendo al carro :-)

Inspirado por ¿Cómo encuentro a Waldo con Mathematica y el seguimiento? Cómo encontrar a Waldo con R , como nuevo usuario de Python, me encantaría ver cómo se puede hacer esto. Parece que Python sería más adecuado para esto que R, y no tenemos que preocuparnos por las licencias como lo haríamos con Mathematica o Matlab.

En un ejemplo como el siguiente, simplemente usar rayas no funcionaría. Sería interesante si se pudiera hacer un enfoque simple basado en reglas para trabajar con ejemplos difíciles como este.

He agregado la etiqueta [machine-learning] porque creo que la respuesta correcta tendrá que usar las técnicas ML, como el enfoque Restricted Boltzmann Machine (RBM) defendido por Gregory Klopper en el hilo original. Hay un código de RBM disponible en python que podría ser un buen lugar para comenzar, pero obviamente se necesitan datos de entrenamiento para ese enfoque.

En el Taller Internacional IEEE 2009 sobre APRENDIZAJE DE LA MÁQUINA PARA EL PROCESAMIENTO DE SEÑALES (MLSP 2009) se realizó una Competencia de Análisis de Datos: ¿Dónde está Wally? . Los datos de entrenamiento se proporcionan en formato de matlab. Tenga en cuenta que los enlaces en ese sitio web están muertos, pero los datos (junto con el origen de un enfoque adoptado por Sean McLoone y sus colegas se pueden encontrar here (ver enlace SCM). Parece un lugar para comenzar.


Aquí hay una implementación con 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))

Divide en canales rojos, verdes y azules. Es mejor utilizar la aritmética de coma flotante a continuación, por lo que convertimos en la parte superior.

w = wfloat.mean(2)

w es el canal blanco.

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

Construya un patrón de + 1, + 1, -1, -1 en el eje vertical. Esta es la camisa de Wally.

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

Convolucionar con rojo menos blanco. Esto dará una fuerte respuesta donde está la camisa.

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

Busque el valor máximo y dilatarlo para hacerlo visible. Ahora, atenuamos la imagen completa, excepto la región o el interés:

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

Y obtenemos !


Esto no es imposible, pero es muy difícil porque realmente no hay ejemplos de una pareja exitosa. A menudo hay varios estados (en este caso, más ejemplos de dibujos de walleys), puede alimentar múltiples imágenes en un programa de reconización de imágenes y tratarlas como un modelo de markov oculto y usar algo así como el algoritmo de viterbi para la inferencia ( http://en.wikipedia.org/wiki/Viterbi_algorithm ).

Esa es la forma en que lo abordaría, pero suponiendo que tienes múltiples imágenes, puedes darle ejemplos de la respuesta correcta para que pueda aprender. Si solo tiene una imagen, lamento que tal vez sea necesario otro enfoque.


Podría intentar la coincidencia de plantillas, y luego eliminar lo que produce el mayor parecido, y luego usar el aprendizaje automático para reducirlo más. Eso también es muy difícil, y con la precisión de la coincidencia de plantillas, es posible que solo devuelva cada cara o imagen similar a una cara. Estoy pensando que necesitarás algo más que aprendizaje automático si esperas hacer esto de manera consistente.


Reconocí que hay dos características principales que casi siempre son visibles:

  1. la camisa a rayas rojo-blanco
  2. cabello castaño oscuro debajo de la elegante gorra

Entonces lo haría de la siguiente manera:

búsqueda de camisetas a rayas:

  • filtra el color rojo y blanco (con umbrales en la imagen convertida HSV). Eso te da dos imágenes de máscara.
  • agrégalos juntos -> esa es la máscara principal para buscar camisas a rayas.
  • cree una nueva imagen con todo el rojo filtrado convertido a rojo puro (# FF0000) y todo el blanco filtrado convertido a blanco puro (#FFFFFF).
  • Ahora correlacione esta imagen pura de blanco y rojo con una imagen de patrón de franjas (creo que todos los waldo tienen franjas horizontales bastante perfectas, por lo que la rotación del patrón no debería ser necesaria). Haga la correlación solo dentro de la máscara principal mencionada anteriormente.
  • intente agrupar grupos que podrían haber sido el resultado de una camisa.

Si hay más de una "camisa", es decir, más de un grupo de correlaciones positivas, busque otras características, como el cabello castaño oscuro:

buscar cabello castaño

  • filtrar el color de cabello marrón específico utilizando la imagen convertida HSV y algunos umbrales.
  • busca un área determinada en esta imagen enmascarada, no demasiado grande ni demasiado pequeña.
  • ahora busque un "área de cabello" que esté justo encima de una camisa a rayas detectada (antes) y que tenga una cierta distancia al centro de la camisa.

tal vez deberías comenzar por dividir el problema en dos más pequeños:

  1. crea un algoritmo que separa a las personas del fondo.
  2. entrenar un clasificador de red neuronal con tantos ejemplos positivos y negativos como sea posible.

esos son todavía dos problemas muy grandes para abordar ...

Por cierto, yo elegiría c ++ y abrir CV, parece mucho más adecuado para esto.


Aquí hay una solución que usa redes neuronales que funciona bien.

La red neuronal está entrenada en varios ejemplos resueltos que están marcados con cuadros delimitadores que indican dónde aparece Wally en la imagen. El objetivo de la red es minimizar el error entre el cuadro predicho y el cuadro real de los datos de entrenamiento / validación.

La red anterior usa la API de detección de objetos de Tensorflow para realizar entrenamientos y predicciones.