Get middle color on bufferedimage and bufferedimage as fast as possible

I am trying to find an image in an image. I do this to automate the desktop. At this moment I try to be fast, accurate. So I decided to match a similar image solely on the basis of the same average color.

If I find several desktop icons, for example:

several desktop icons

And I will look for the latter (I'm still wondering what kind of file it is):

some file icon

You can clearly see what will most likely correspond:

image displaying average colors in regions

In different situations, this may not work. However, when the image size is set, it should be fairly reliable and lightning fast.

I can get a screenshot as an object BufferedImage:

MSWindow window = MSWindow.windowFromName("Firefox", false);
BufferedImage img = window.screenshot();
//Or, if I can estimate smaller region for searching:
BufferedImage img2 = window.screenshotCrop(20,20,50,50);

Of course, the search image will be loaded from the template saved in the file:

BufferedImage img = ImageIO.read(...whatever goes in there, I'm still confused...);

, , , :

  • Q: ? - ?

. , .

+3
2

, , , O(wh), w - , h - .

() , , , .

/*
 * Where bi is your image, (x0,y0) is your upper left coordinate, and (w,h)
 * are your width and height respectively
 */
public static Color averageColor(BufferedImage bi, int x0, int y0, int w,
        int h) {
    int x1 = x0 + w;
    int y1 = y0 + h;
    long sumr = 0, sumg = 0, sumb = 0;
    for (int x = x0; x < x1; x++) {
        for (int y = y0; y < y1; y++) {
            Color pixel = new Color(bi.getRGB(x, y));
            sumr += pixel.getRed();
            sumg += pixel.getGreen();
            sumb += pixel.getBlue();
        }
    }
    int num = w * h;
    return new Color(sumr / num, sumg / num, sumb / num);
}
+3

, . . 3d- . , 3 , .

, 2- , "img".

- , , , .

:

int width = 1920;
int height = 1080;

//source data
int[] img = GrayScaleScreenCapture();
int[] helperImg = int[width * height]

for(int y = 0; y < width; ++y)
{
    for(int x = 0; x < height; ++x)
    {
        int total = img[y * width = x];

        if(x > 0)
        {
            //Add value from the pixel to the left in helperImg
            total += helperImg[y * width + (x - 1)];
        }

        if(y > 0)
        {
            //Add value from the pixel above in helperImg
            total += helperImg[(y - 1) * width + x];
        }

        if(x > 0 && y > 0)
        {
            //Subtract value from the pixel above and to the left in helperImg
            total -= helperImg[(y - 1) * width + (x - 1)];
        }

        helperImg[y * width + x] = total;
    }
}

helperImg, img :

//Some Rectangle with corners (x0, y0), (x1, y0) , (x0, y1), (x1, y1)
int x0 = 50;
int x1 = 150;
int y0 = 25;
int y1 = 200;

int totalOfRect = helperImg[y1 * width + x1];

if(x0 > 0)
{
    totalOfRect -= helperImg[y1 * width + (x0 - 1)];
}

if(y0 > 0)
{
    totalOfRect -= helperImg[(y0 - 1) * width + x1];
}

if(x0 > 0 && y0 > 0)
{
    totalOfRect += helperImg[(y0 - 1) * width + (x0 - 1)];
}

, totalOfRect , :

int rWidth = x1 - x0 + 1;
int rheight = y1 - y0 + 1;

int meanOfRect = totalOfRect / (rWidth * rHeight);
0

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


All Articles