Trabajar con imágenes

Hola a todos.

Estoy comenzando a trabajar con imágenes en java, tengo un proyecto para la escuela, es un sistema para vigilar intrusos con una cámara, hasta ahora todo bien, mi idea es ir tomando parejas de imágenes en intervalos pequeños de tiempo del vídeo y luego comparar esas imágenes, pero no tengo ni idea de como comparar si dos imágenes son iguales, es decir, vi códigos que comparan pixel a pixel, pero las imagenes que tomo del video siempre difieren un poco, así que no se como compararlas

qué debo hacer?
pensé en tratar la imagen, pero es la primera vez que trabajo con esto, qué clases me recomiendan usar, o algoritmos ó algo, I am stuck :(

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

interesante algoritmo

Puedes de manera muy básica, creo que algo que puedes hacer es dividir la imagen en regiones (suponte, unas 16 regiones, o sea una cuadrícula de 4x4, pero te sugiero que dejes configurable esa resolución). A cada sub-imagen puedes aplicarle un algoritmo para sacar el "promedio" por decirle de alguna forma: Un valor numérico que defina a toda la región. Puede ser el color promedio, o el más dominante en la imagen.

Cuando aplicas eso en dos imágenes, tienes valores numéricos fácilmente comparables entre ambas imágenes; si N valores son distintos entre ambas imágenes, es que algo cambió. Y también deberías considerar un umbral de diferencia entre imágenes, porque si te pones muy estricto, un simple cambio en la iluminación puede disparar la alarma (como al anocher o al amanecer o si de repente se nubla y el área vigilada es iluminada aunque sea parcialmente por luz natural).

Es algo así como aplicar ese filtro de Gimp o Photoshop para "pixelar" una imagen, pero se lo aplicas a toda la imagen y así terminas haciendo una comparación pixel por pixel PERO no de toda la imagen sino de una versión muy simplificada de la misma. Por lo tanto, la transformación la puedes hacer con algoritmos existentes, ya sea ese filtro de pixelar, o una transformación para escalar tu imagen a algo como 64x64 (como un vil thumbnail) y luego comparas imágenes pequeñas. La resolución la debes determinar tú, según lo que quieras detectar: haz pruebas teniendo una imagen de referencia, del área vacía, y varias imágenes, con una persona parada en distintas partes del área vigilada; reduce las imágenes con la persona a tamaños donde veas que haya una diferencia significativa con la imagen de referencia.

Tengo entendido que una imagen es un arreglo de bytes.

Pues si hacemos uso de lo que te dicen cómo teoría en las clases de programación: "una imagen es un arreglo de bytes"; ¿porqué no comparas los arreglos?...Ya si quieres ser más exacto puedes comparar byte con byte. Aunque la versión de @ezamudio suena interesante.

@wishmaster77 Porque

@wishmaster77 Porque precisamente como dice Hugo, en un video aunque no haya nada de cambio, la imagen siempre tiene un contenido diferente de un segundo a otro.

Supon que en un arreglo de bytes una sección de la imagen ( realmente pequeñitita ) aparece algo como esto:

[0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2]

Que podría ser una esquinita negra o algo así, y un segundo después aparece esto:

Y el siguiente segundo dice:

[0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3]
 

Que es la misma esquinita pero ligeeeeramente más clara ( de 0x02 a 0x03 que es nada ) este cambio no debería de disparar ninguna detección.

Por eso, lo que dice Enrique es transformar la imagen para que sean cuadros más grandes y se pueda detectar más fácilmente un cambio significativo.

Un post interesante ( aunque no tiene que ver con la solución ) es la forma en la que en GitHub se detectan cambios en las imagenes:

https://github.com/blog/817-behold-image-view-modes

Ejemplo:

Ya no revisé si el código está disponible o no.

Re: @wishmaster77 Porque

mmm...Bueno ahí dependería el tipo de vídeo, la cámara etc. Si es en un espacio abierto es la solución bytera no sirve de mucho (sobretodo por el cambio en la iluminación). En un espacio cerrado la opción del byte aplica para ciertos casos, pero creo que para lo que quiere hacer Hugo es un algoritmo tipo "Smile Shutter", ahí la cosa ya está más macabra; aplica el uso de reconocimiento ocular ahí si ya "llegué más de lo que mi jurisdicción permite" xD!.

Imagen de rodrigo salado anaya

Unas cuantas ligas que espero te sirvan

Imagen de bferro

El problema no es trivial

Para manipular imágenes, sean éstas estáticas o frames de vídeo se utilizan algoritmos complejos donde la matemática sí es obligada y no una opción.
Hay muchos marcos de trabajo para eso, tanto en Java como en otros lenguajes, pero antes de usarlos, hay que conocer lo que de ellos se quiere usar. Incluyen diversas técnicas probabilísticas, de topología matemática, de reconocimiento de patrones y muchas cosas más. Abundan más las bibliotecas en lenguaje C, algunas comerciales y otras de open source.
Pero si quieres enfrentar el problema con seriedad, nadie de va a quitar del camino lo que necesitas asimilar de esa matemática.
Existen varios algoritmos para la comparación de imágenes, que se seleccionan de acuerdo con lo que se persigue en esa comparación: contenido fundamental de la imagen, tolerancia en la comparación, etc.
Algunos de esos algoritmos son: "correspondencia de puntos claves", comparación de los histogramas de las imágenes, árboles de decisión clasificadores de imágenes, etc.
Casi ningún problema de procesamiento de imágenes se basa en comparar exactamente las imágenes, considerándolas como simples arreglos bidimensionales.
Una vez más: hay que entrarle a las mates, y esto lo digo para aquellos que consideran que las matemáticas no hacen falta, que ya son varios en este foro.

Es claro quepueda existir una

Es claro quepueda existir una diferencia debido a la compresion de la imagen que obtengas... a mi se me ocurre en vez de aplicar un efecto de pixeleado mejor pongas un efecto de desenfoque porque eso va a fusionar progresivamente los colores en lugar de volverlos mas asperos en la comparativa.

Aqui hay una imagen nitida y otra dañada por efectos de compresion de imagen
imagen normal imagen comprimida

Habrás notado que si comparas pixel a pixel las cosas se puden poner bien rudas (y eso que esta compresión de imagen no se compara con la del video... ahora, después de aplicar un desenfoque, te daras cuenta que los cambios de tonos entre pixeles es mas suave (no por nada se llama tambien suavizado)

imagen normal imagen comprimida

Sé que esto no soluciona completamente pero puede que te sirva juntar algunas ideas mas que aquí he leído

Re: El problema no es trivial

Perdón si se notó que quise decir que era cómo preparar enchiladas; lejos estaba de eso. Mi primer comentario fue porqué no había entendido bien la problemática, una vez explicada vi que lo que se busca es una funcionalidad similar a la de Smile Shutter que no es ni sencilla y mucho menos nada tediosa, por el contrario creo que mis conocimientos ya no tienen que andar haciendo aquí porqué poco se de manejo de imágenes y de comparación con reconocimiento de patrones sobre una imagen mucho menos.

Respecto a las matemáticas, es cierto son necesarias para todo y siendo ingeniero es un deber tener bases de matemáticas y de ser posible ir un poco más allá de las bases. Incluso muchos las usamos en el día a día sin darnos cuenta (álgebra relacional -con las bases de datos-, probabilidad y estadística -generando reportes- y otras cosas que ahora no me vienen a la mente).

Imagen de rodrigo salado anaya

Dangerous Knowledge

In this one-off documentary, David Malone looks at four brilliant mathematicians - Georg Cantor, Ludwig Boltzmann, Kurt Gödel and Alan Turing - whose genius has profoundly affected us, but which tragically drove them insane and eventually led to them all committing suicide.

The film begins with Georg Cantor, the great mathematician whose work proved to be the foundation for much of the 20th-century mathematics. He believed he was God's messenger and was eventually driven insane trying to prove his theories of infinity.

http://www.youtube.com/watch?v=Cw-zNRNcF90

Imagen de HugoRmz

Hey gracias a todos !!

Después de varios días de trabajar con ese proyecto lo logré, bueno no detecta asi particulas de polvo, pero empezé con el algoritmo de @ezamudio dividi la imagen en 20*20 partes... aunque no reconoce cambios pequeños, mi programa logra reconocer cuando entran personas a un cuarto iluminado .. me saqué un 10 !!! GRACIAS !!!

cuando eleji mi proyecto lo hice porque creia que era facil jajaja; es que cuado lo lei decía:
"realizar un programa que reconosca intrusos mediante una camara de vigilancia" pense... pues nadamas tomo parejas de imagenes las comparo y yap jaja pero noooo, lo bueno es que aprendí algo nuevo ..... debería existir una clase que tenga el método bool laImagenTieneUnIntruso(imagen);
=P

Imagen de HugoRmz

(Sin asunto)

Comparte código, comparte.

Comparte código, comparte. Digo a menos que pienses patentarlo y esas cosas, creo que ser podría aprender mucho de ahí. Y si no ya de plano un videito de él funcionando.

Saludos y felicidades.

Imagen de Jose Manuel

Open Source!!

Ah!!, es lo que apenas le iba a escribir...
Pero si, compártelo, que a muchos les puede ser útil después. Y no me digas que si lo vas a patentar...
Que bien que lo lograste!! en hora buena!
Saludos!

Imagen de CybJer

La manera mas adecuada como

La manera mas adecuada como comenta bferro es el reconocimiento de patrones, ademas no vas a tratar una imagen asi simplemente, debes recordar que en realidad la imagen tiene 3 canales RGB y cada canal esta es una matriz de bytes del mismo tamaño que tu imagen en pixeles, en realidad no tienes un solo arreglo si no son 3.
Es importante que busques una transformacion de imagen que te facilite el tener en 1 solo canal (Una sola matriz) la informacion mas representativa o la informacion que te es mas util para realizar un procedimiento de reconociomiento como el que planteas.
Este paso que menciono es critico para lograr que tu trabajo tenga un desempeño aceptable y el consumo de recursos en la aplicacion no sea exagerada, imaginate comprobar pixel por pixel en una imagen a color RGB de 1600*1200 pixeles (que es una resolucion de una camara como la de mi telefono 2.3 megapixeles) eso nos daria comprobar 3 arreglos con 1920000 bytes cada uno y eso multiplicado por 2 que son las imagenes a comparar.
Busca un algoritmo que haga algo similar a lo que necesitas (reconocer figuras humanoides), tambien tienes que entrenar a tu sw para hacerlo mas especializado (comparar contra patrones de lo que si es una figura humanoide y cual no) .

Imagen de ezamudio

patentar

Tendrías que ir a USA a patentarlo, porque afortunadamente el software en México no es patentable. Puedes registrarlo en el INDAUTOR pero no patentarlo (y sí, por tanto, nada de esos rollos de patentes de SW aplican en México).

CybJer: 4 comentarios arriba del tuyo, nos platica HugoRmz que ya solucionó su problema. Los siguientes 2 comentarios son para pedirle que muestre su solución...

Imagen de CybJer

¿Seguro que solo reconoce

¿Seguro que solo reconoce personas?, que tal entra un perro grande, avientan una pelota, o se abre la puerta con el viento, etc.
@ezamudio Ok: Ya lei (bastante tarde ) aunque no considero que este de mas por si alguien se topa con algo similar busque una solucion alterna