Найти цвет с допуском в буферизованном изображении

1

Я пишу метод, который попытается найти цвет в bufferedImage. На данный момент метод работает, беря screencap, а затем просматривает изображение для определенного цвета. Теперь я хотел бы добавить некоторую допустимость RGB, поэтому, если пользователь пытается найти цвет (1, 3, 5) с допуском 1, любой цвет +-1 R, B или G вернет true.

Я мог бы решить это, сначала создав массивList значений RGB, которые работают, а затем для каждого пикселя я мог бы пройти через массив и проверить с каждым значением. Проблема в том, что, вероятно, получится ОЧЕНЬ медленно для высоких допусков на больших изображениях.

Есть ли более эффективный или, возможно, встроенный способ, я могу это сделать? Вот мой метод, поскольку он стоит прямо сейчас. Спасибо!

public static Point findColor(Box searchArea, int color){
    System.out.println("Test");
    BufferedImage image = generateScreenCap(searchArea);
    for (int i = 0; i < image.getWidth(); i++) {
        for (int j = 0; j < image.getHeight(); j++) {
            if((image.getRGB(i, j)*-1)==color){
                return new Point(i + searchArea.x1, j + searchArea.y1);
            }
        }
    }
    return new Point(-1, -1);
}

Изменение: я использую значения int RGB для всех сравнений, поэтому вместо Color [1, 1, 1] я использую Color.getRGB(), который возвращает отрицательный int, который я конвертирую в положительный для простоты пользователя.

  • 0
    Почему это будет медленно для больших допусков на больших изображениях?
  • 0
    @ForguesR В изображении 800x600, это 480 000 пикселей, которые необходимо проверить. Проверка на 1 цвет в каждом из этих пикселей в порядке, скорость в порядке, но представьте себе, что вы проверяете 100 различных цветов в каждом из 480 000 пикселей, внезапно он в 100 раз медленнее. Эффективность является огромным приоритетом в этом проекте, поэтому, если есть способ сделать это быстрее, это было бы здорово
Показать ещё 2 комментария
Теги:
rgb
colors
awt
awtrobot

1 ответ

1
Лучший ответ

Вам нужно сравнить значения RGB, а не "весь" цвет, если вы хотите иметь пользовательский допуск. Вот код, он не протестирован, но вы получаете идею:

public static Point findColor(Box searchArea, int r, int g, int b, int tolerance){
    System.out.println("Test");

    // Pre-calc RGB "tolerance" values out of the loop (min is 0 and max is 255)
    int minR = Math.max(r - tolerance, 0);
    int minG = Math.max(g - tolerance, 0);
    int minB = Math.max(b - tolerance, 0);
    int maxR = Math.min(r + tolerance, 255);
    int maxG = Math.min(g + tolerance, 255);
    int maxB = Math.min(b + tolerance, 255);

    BufferedImage image = generateScreenCap(searchArea);
    for (int i = 0; i < image.getWidth(); i++) {
        for (int j = 0; j < image.getHeight(); j++) {
            // get single RGB pixel
            int color = image.getRGB(i, j);

            // get individual RGB values of that pixel
            // (could use Java Color class but this is probably a little faster)
            int red = (color >> 16) & 0x000000FF;
            int green = (color >>8 ) & 0x000000FF;
            int blue = (color) & 0x000000FF;  

            if ( (red >= minR && red <= maxR) &&
                 (green >= minG && green <= maxG) &&
                 (blue >= minB && blue <= maxB) ) 
                return new Point(i + searchArea.x1, j + searchArea.y1);
        }
    }
    return new Point(-1, -1);
}
  • 0
    Это не работает, но я понимаю, я должен быть в состоянии сформировать и сформировать метод, чтобы заставить его делать то, что я хочу. Благодарю вас!
  • 0
    Рад, что смог помочь. Можете ли вы сказать мне, что не работает?
Показать ещё 8 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню