How to match similar colors in Java using getRGB

I take screenshots using a robot, and then searched for smaller images in these screenshots. This works on Windows, but not on OS X due to gamma correction. The best solution I can come up with is just to match similar colors instead of exact color matches.

My fear is that matching similar colors would mean going beyond getRGB, so it will slow down my program (because it takes a few screenshots and compares them with a smaller image to find a match very quickly).

My question is: let's say I had a BufferedImage Screenshot and a BufferedImage smallImage, how would I decide to determine if the colors of Screenshot.getRGB (1,1) and smallImage.getRGB (1,1) are similar?

+6
source share
3 answers

There is an interesting article on this issue:

A new perception of a uniform color space with an appropriate criterion for color similarity for the content image and video of M. Sarifuddin and Rokia Missaui

You can easily find this using Google or, in particular, Google Scholar.

To summarize, some color spaces (e.g. RGB, HSV, Lab) and distance measurements (e.g. geometric mean and Euclidean distance) are better representations of human perception of color similarity than others. The document talks about a new color space that is better than the rest, but it also provides a good comparison of common existing color spaces and distance measures. Qualitatively *, it seems, the best measure for perceiving distance using commonly available color spaces is: HSV color space and cylindrical distance measure.

* At least as shown in Figure 15 in the reference article.

Cylindrical distance measure (in latex notation):

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

Also pay attention to some similar questions that address the same issue:

search for similar colors programmatically

The "distance" between colors in PHP

Finally, in Java there is an easy way to convert from RGB values ​​to other color spaces:

ColorSpace.fromRGB

+4
source

For color similarity, DR=R1-R2 , DG=G1-G2 , DB=B1-B2 , then calculate DR×DR+DG×DG+DB×DB and take the square root of this and compare it with some threshold value. Of course, this can be optimized by simply skipping the square root part and simply raising the square to the threshold.

But you might be better off if you somehow manage to get OSX to display a PNG containing your image on the screen, then read this part of the screen, and then look for an exact match for this.

+1
source

Do you use this getRGB method? If so, I would compare the elements of the array from 1 to 3 (RGB) with each other, subtracting them and checking whether the absolute value of this value is below a given threshold (for example, 10). So it will be something like

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

without if statement:

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

Of course, you need to copy it for both green and blue. Hope this helps, Christoph

0
source

Source: https://habr.com/ru/post/904808/


All Articles