2011-12-31 18 views
6

Estoy tomando capturas de pantalla de la pantalla usando un robot y luego buscando imágenes más pequeñas dentro de esas capturas de pantalla. Esto funciona en Windows pero no en OS X debido a la corrección gamma. La mejor solución que se me ocurre es simplemente combinar colores similares en lugar de coincidencias de color exactas.Cómo unir colores similares en Java usando getRGB

Mi temor es que igualar colores similares signifique ir más allá de getRGB, por lo tanto ralentizará mi programa (porque está tomando múltiples capturas de pantalla y comparándolas con una imagen más pequeña para buscar una coincidencia muy rápidamente).

Mi pregunta es, digamos que tenía BufferedImage pantalla y BufferedImage SmallImage, ¿cómo hago para determinar si Screenshot.getRGB (1,1) y (1,1) smallImage.getRGB son similares colores?

+0

que solicitó en un comentario acerca de una manera más rápida de conseguir que los valores de píxeles * getRGB * ... * * getRGB puede ser de hecho terriblemente lento: en algunas versiones de OS X puede ser de hasta dos órdenes de magnitud (sí, cien veces más lento [!], medido en OS X 10.4) más lento que obtener directamente los valores de píxel del * int [] * subyacente. Vea mi respuesta (aceptada) aquí sobre una forma más rápida de extraer un histograma de una imagen: http://stackoverflow.com/questions/8218072/faster-way-to-extract-histogram-from-an-image/8218570#8218570 Una técnica similar podría aplicarse en su caso para que ambos sean más rápidos y eviten la corrección gamma. – TacticalCoder

Respuesta

4

Hay un interesante artículo sobre exactamente este problema:

Una nueva Perceptualmente uniforme del espacio de color con Asociada similitud de colores Medida por basada en contenido y recuperación de imágenes de vídeo por M. Sarifuddin y Rokia Missaoui

puede encontrar esto fácilmente usando Google o en particular Google Scholar.

Para resumir, algunos espacios de color (p. RGB, HSV, Lab) y las medidas de distancia (como la media geométrica y la distancia euclidiana) son mejores representaciones de la percepción humana de la similitud de color que otras. El documento habla sobre un nuevo espacio de color, que es mejor que el resto, pero también proporciona una buena comparación de los espacios de color existentes comunes y las medidas de distancia. Cualitativamente *, parece que la mejor medida para la distancia de percepción usando espacios de color comúnmente disponibles es: el espacio de color HSV y una medida de distancia cilíndrica.

* Al menos, de acuerdo con la Figura 15 en el documento al que se hace referencia.

La medida de distancia es cilíndrica (en notación de látex):

D_ {cil} = \ sqrt {\ Delta V^{2} + S_1^{2} + S_2^{2} -2S_1S_2cos (\ Delta H)}

también tenga en cuenta que hay algunas preguntas similares que abordan el mismo tema:

finding similar colors programatically

"Distance" between colours in PHP

Finalmente, en J ava, no hay ninguna manera fácil de convertir de valores RGB en otros espacios de color:

ColorSpace.fromRGB

1

Por similitud de color, vamos DR=R1-R2, DG=G1-G2, DB=B1-B2, a continuación, calcular DR×DR+DG×DG+DB×DB y tomar la raíz cuadrada de eso, y lo comparan con un valor umbral. Por supuesto, esto se puede optimizar simplemente omitiendo la parte de raíz cuadrada y simplemente cuadrando el umbral.

Pero podría estar mejor si logra que OSX muestre un PNG que contenga su imagen en pantalla, luego lea esa parte de la pantalla y luego busque una coincidencia exacta con eso.

+0

La tuya es una media geométrica, creo. ¿Cómo es esto mejor que usar un cálculo de distancia euclidiana? En pseudocódigo, 'sqrt (sqr (r1-r2) + sqr (g1-g2) + sqr (b1-b2))' –

+0

Perdóneme por preguntar, pero ¿hay una forma más eficiente de obtener valores RGB de una coordenada de píxel distinta? que romperlo después de llamar a getRGB()? Me encantaría saber cómo configurar captureScreen en el robot para representar capturas de pantalla de OS X correctamente con una mejor corrección de gamma similar a Windows, pero no sé cómo hacerlo. – Macmee

+0

@HovercraftFullOfEels maldito Alzheimer. Corregiré mi respuesta. –

0

¿Está usando this Método getRGB? En caso afirmativo, compararía los elementos de la matriz 1 a 3 (RGB) entre sí restándoles y verificando si el valor absoluto de esto está por debajo de un umbral determinado (por ejemplo, 10). por lo que sería algo así como

if(Math.abs(firstPixel[1]-secondPixel[1])<10) 
    redIsSimilar = true; 
else 
    redIsSimilar=false; 

sin sentencia if:

redIsSimilar = Math.abs(firstPixel[1]-secondPixel[1]) < 10; 

Por supuesto, es necesario copiar pegar este para el verde y el azul también. Espero que esto ayude, Christoph

+0

Estoy usando getRGB de la clase BufferedImage aquí http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/image/BufferedImage.html#getRGB(int, int) – Macmee

Cuestiones relacionadas