Java выходит за рамки с сопоставлением шаблонов

Недавно я заинтересовался сопоставлением шаблонов, я знаю, что существуют такие библиотеки, как OpenCV, но я хотел создать простую функцию для поиска всех точек, где шаблон можно найти в поиске BufferedImage, без необходимости каких-либо дополнительных библиотек или установки программного обеспечения и т. д.

Я нашел статью на вики об этом, которая содержала некоторый код:

http://en.wikipedia.org/wiki/Template_matching

Кажется, он делает именно то, что мне нужно, поэтому я перенес его на Java, но вместо того, чтобы использовать оттенки серого, немного изменил его, чтобы использовать цвета. Тестирование со сплошным белым изображением шаблона (30x30) и изображением поиска (508x307), которое также является сплошным белым, но с красными прямоугольниками в некоторых областях, код, кажется, некоторое время правильно выводится на консоль, однако затем я получаю ошибки:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Coordinate out of bounds!
    at sun.awt.image.ByteInterleavedRaster.getDataElements(Unknown Source)
    at java.awt.image.BufferedImage.getRGB(Unknown Source)
    

Я не уверен, связано ли это с тем, что это не оттенки серого, или с тем, что java требует дополнительных настроек количества циклов, но любая помощь в правильной работе будет оценена по достоинству.

public Point[] TemplateMatchBI(BufferedImage Search, BufferedImage Template){

// Point list
ArrayList<Point> temp = new ArrayList<Point>(); 

//Matched Colors Boolean
boolean m = false; 

//Current Index, Matched Colors Count, Search Color (Int), Template Color (Int)
int index = 0, mcc = 0, sc = 0, tc = 0; 

// Quick Strings
String s01 = "Index = ", s02 = ", Search color = ", s03 = ", Template color = ", 
s04 = ", Matched? = ", s05 = ", Matched? = ", s06 = ", Template scan = ";

// Loop through the search image
for ( int x = 0; x <= Search.getHeight() - Template.getHeight(); x++ ) {
    for ( int y = 0; y <= Search.getWidth() - Template.getWidth(); y++ ) {

        // Loop through the template image
        for (int i = 0; i < Template.getHeight(); i++)
            for (int j = 0; j < Template.getWidth(); j++) {

                sc = Search.getRGB(x+i, y+j); // Set Search Color
                tc = Template.getRGB(i, j); // Set Template Color
                
                index++; // Increase index int
                m = false; // Reset m to false
                
                if ( sc == tc ){ // If the Search and Template Colors match then
                    mcc++; // Increase match count
                    m = true; // Colors match
                    //temp.add(new Point(i, j)); // Template scan point
                }

                Log(s01 + index + s02 + sc + s03 + tc + s04 + m + s05 + mcc + s06 + new Point(x, y));
                //Log("i = " + i + ", j = " + j + ", point = " + new Point(x+i, y+j));
            }
        }
    }
Point[] tempReturn = new Point[temp.size()];
temp.toArray(tempReturn);
return tempReturn;
}

Изображения, которые я тестирую:

Template.png (он сплошного белого цвета, поэтому выглядит невидимым на странице)

Template.png

Поиск.png

Search.png


person zeddex    schedule 04.10.2012    source источник
comment
Бьюсь об заклад, если вы измените <= в x <= Search.getHeight() на < (и, соответственно, в y <= Search.getWidth()), вы добьетесь большего успеха, но вы должны попытаться распечатать индексы по ходу дела, чтобы узнать, какие из них взрывают его.   -  person Daniel Lyons    schedule 04.10.2012
comment
Спасибо, я только что попробовал это, однако после индекса 250229 такая же ошибка.   -  person zeddex    schedule 04.10.2012
comment
Попробуйте распечатать свои координаты, а не значение индекса.   -  person Daniel Lyons    schedule 04.10.2012


Ответы (1)


Кажется, что вики дает неправильный код, а X и Y перевернуты, когда они меняются местами, кажется, что это работает.

person zeddex    schedule 10.10.2012