2010-01-10 23 views
9

¿Cuál es el mejor enfoque para comparar dos imágenes con php y Graphic Draw (GD) Library?Comparación de imágenes con php + gd

Este es el escenario:

alt text http://img262.imageshack.us/img262/4849/imagecomparison.jpg

tengo una imagen, y quiero encontrar cuál es la imagen de un conjunto dado es la más parecida a ella. La imagen más similar es, de hecho, la misma imagen, no la combinación perfecta de píxeles pero la misma imagen. He dramatizado la diferencia entre las dos imágenes con el número uno en el ejemplo solo para facilitar la comprensión de lo que quería decir.

Aunque no trajo resultados consistentes, mi enfoque fue reducir las imágenes a 1px usando la función imagecopyresampled y ver qué tan cerca estaban los valores RGB entre las imágenes.

La suma de los valores de deducir cada valor equivalente decimal rojo, verde y azul del equivalente decimal rojo, verde y azul de la posible coincidencia me dio un índice de disimilitud que, aunque no funcionó como se esperaba desde no siempre la imagen más similar a RGB era la imagen de destino, podría usar para seleccionar una imagen de los objetivos disponibles.

He aquí una muestra de la salida al comparar 4 imágenes de una imagen deseada en contra, en este caso el logo de la manzana, que coincide con uno de ellos, pero no es exactamente el mismo:

imagen original:

http://www.lshtm.ac.uk/its/remote/images/os-apple.png rojo: 222 verde: 226 azul: 232

Comparado contra:

http://a1.twimg.com/profile_images/571171388/logo-twitter_normal.png Red: 183 verde: 212 Azul: 212 y un índice de similitud de 56

http://icons-search.com/img/fasticon/fruits_lnx.zip/fruits_lnx-Icons-48X48-apple.png-48x48.png Red: 117 verde: 028 Azul: 028 y un índice de disimilitud 530

http://www.1sd.org/wp-content/uploads/2008/10/48x48-apple.png Red: 218 Verde : 221 Azul: 221 y un índice de disimilitud Coincide correctamente.

Rojo: 061 Verde: 063 Azul: 063 y un índice de disimilitud 491

puede incluso no ser factible mejor con mejores resultados de lo que ya estoy haciendo y estoy perdiendo el tiempo aquí pero dado que parece que hay muchos programadores de php con experiencia, creo que puedes orientarme sobre cómo mejorar esto.

Estoy abierto a otras bibliotecas de imágenes como iMagick, Gmagick o Cairo para php, pero prefiero evitar el uso de otros idiomas distintos de php.

Gracias de antemano.

+0

¿Así que quieres ganarle al captcha? –

+0

No es un captcha, las imágenes son las mismas que dije, no giradas, no hay líneas en el medio, no hay borrosidad. Es parte de un proyecto más grande que tengo y parece que no puedo pasar esto de manera efectiva. – johnnyArt

+0

Posible duplicado de [¿Cómo detectar imágenes similares en PHP?] (Https://stackoverflow.com/questions/4602562/how-to-detect-similar-images-in-php) – DanMan

Respuesta

4

Hubiera pensado que su enfoque parece razonable, pero reducir una imagen entera a 1x1 pixel de tamaño es probablemente un paso demasiado lejano.

Sin embargo, si convirtió cada imagen al mismo tamaño y luego calculó el color promedio en cada celda de 16x16 (o 32x32, 64x64, etc., según el tiempo de procesamiento/potencia que desea usar), debería poder para formar algún tipo de comparación sensible (-ish).

+0

Terminé usando mi código y desde entonces dijo que era razonable, entonces oye, recibes la respuesta aceptada – johnnyArt

+0

Perdón por agitar un hilo viejo, pero estoy exactamente en la misma situación. Gracias al enlace imagecopyresampleado puedo cambiar el tamaño de las imágenes, pero ¿cómo exactamente puedo calcular el color promedio en cada imagen de 16x16? –

+1

@ Marci-man En un nivel muy básico, puede usar imagecolorat para obtener los valores RGB para los píxeles dentro de esa "celda" y promediarlos para obtener un valor para la celda como un todo. –

-1

Usando los métodos de middparka, puede transformar cada imagen en una secuencia de valores numéricos y luego usar the Levenshtein algorithm para encontrar la coincidencia más cercana.

+2

¿Cómo puede el algoritmo de Levenshtein ayudar aquí? Citando "La distancia de Levenshtein entre dos cadenas está dada por el número mínimo de operaciones necesarias para transformar una cadena en la otra" y dado que todas las secuencias estarán formadas por tres números de 2 dígitos, el número de operaciones siempre será 3. A menos que tienen valores idénticos de rojo, verde o azul, lo que no necesariamente significa que sea el color más cercano y, por lo tanto, la imagen más similar. – johnnyArt

+1

Y como una ventaja, PHP ya tiene una función levenshtein: http://php.net/manual/en/function.levenshtein.php – Marko

0

Sugeriría, como middaparka, que no disminuya la resolución de una imagen de 1 píxel, ya que pierde toda la información espacial. Reducir la resolución a 16x16 (o 32x32, etc.) sin duda proporcionará mejores resultados.

Luego, también depende de si la información del color es importante o no para usted. Por lo que entiendo, en realidad podría prescindir de él y calcular una imagen de nivel de gris a partir de su imagen en color (por ejemplo, luma) y calcular la correlación cruzada. Si, como dijiste, hay un par de imágenes que coinciden exactamente (excepto por la información del color), esto debería darte una confiabilidad bastante buena.

Cuestiones relacionadas