2009-12-29 14 views
6

Tengo una imagen almacenada de tipo TYPE_INT_BGR. Necesito hacer una comparación píxel por píxel con otra Imagen Buffered para calcular la "distancia" entre las dos imágenes. Tengo algo que funciona, pero es lento. Consigo un píxel de la imagen de "referencia", dividirla en RGB bytes con:¿La forma más rápida de comparar valores de píxeles entre dos imágenes almacenadas?

int pixel = referenceImage.getRGB(col, row); 
    int red = (pixel >> 16) & 0xff; 
    int green = (pixel >> 8) & 0xff; 
    int blue = (pixel) & 0xff; 

que comparar los valores de R/G/B para el píxel correspondiente de la imagen candidata, y que resume los cuadrados de las diferencias

¿Hay una manera más rápida de hacer este tipo de comparación? Echando un vistazo a la fuente de JRE, veo que BufferedImage.getRGB() está realmente ordenando los valores RGB constituyentes del ráster juntos, lo que es un desperdicio para mis propósitos, ya que simplemente lo estoy dividiendo en bytes nuevamente.

voy a tratar de hacer eso directamente, pero me pregunto si no hay una mejor manera de hacer esto, ya sea a través de una API Java o tercera parte que podría haber perdido.

Respuesta

3

La lectura de datos desde un VolatileImage no serán más rápidos. Lo que hace que VolatileImages sea "más rápido" es que usan memoria acelerada (VRAM) en lugar de memoria del sistema (RAM) para dibujar imágenes. Sin embargo, al leer, es posible que necesite acceder a la memoria sobre otro bus y que sea más lenta que la memoria del sistema para esas operaciones.

La manera más rápida de comparar imágenes con formato de imagen borrosa sería usar comparaciones de enteros de la forma en que discutes en tu publicación, pero como mencionas, no puedes usar getRGB por motivos de rendimiento. Puede obtener un lote de píxeles en una matriz, pero en general, probablemente debería echar un vistazo en el Raster y DataBuffer para el rendimiento.

+0

Tienes razón; Volátil es una mala sugerencia. Lo he corregido. Tristemente, no puedo menospreciar mi respuesta. – Mikeb

+1

Su respuesta fue buena acerca de la comparación de DataBuffer :) –

2

Si ambas imágenes utilizan el mismo modelo de color y toma de muestras, puede realizar su comparación en el DataBuffer de la trama, que será un poco más rápido.

+1

Sí, ambas imágenes utilizan el mismo modelo de color y toma de muestras. Presumiblemente, con DataBuffer, todavía tendré que hacer el cambio de bit, pero quizás al menos evite volver a unir los valores. –

+0

Si sirve de algo, todas las imágenes con las que estoy trabajando son "fuera de pantalla"; uno se lee desde un JPG, el otro se construye desde el dibujo en un Graphics2D. Nunca he usado VolatileImage antes, lo comprobaré. –

2

¿Ha considerado usar Java2D para crear una nueva imagen siendo la diferencia entre las dos imágenes que tiene, y luego analizar la imagen de diferencia en su lugar?

Mi planteamiento inicial sería tomar el negativo de la imagen A y B. agregar la imagen

+0

Esta es una excelente idea :) –

+0

Esto parece una gran idea, pero no he tenido mucha suerte en encontrar ejemplos. Supongo que necesitaría implementar java.awt.CompositeContext. La única implementación de eso que veo es SunCompositeContext, y lamentablemente no se proporciona la fuente. –

1

Si la descomposición de bytes + cargan clases extra es el problema, intente lo siguiente:

conseguir la forma del valor BufferedImage un valor de píxeles RGB

img = 65536*R + 256*G + B - 16777216; 

Conseguir un valor RGB de un valor img BufferedImage

R= Math.round((((371*img)+24576000000)/96000000) 
G= Math.round((65536 + 0.003906*img - 256*R)); 
B= Math.round((65536*R + 256*G -img - 16777216)); 

No estoy seguro si esta es una forma mejor/más rápida de hacerlo, pero es otro método alternativo que no utiliza clases adicionales, y es un proceso matemático directo (o un truco) ... Esto puede ser útil en algunas ocasiones (por favor verifique nuevamente ya que es mi propio método que no tuve tiempo suficiente para jugar).

no sé sobre el tipo de comparación que necesitaba entre los valores de píxeles, por lo que este es hasta qué punto este post va ... espero que alguien realmente cree que esta ayuda!

Cuestiones relacionadas