2017-01-05 4 views
0

Я использую сопоставление шаблонов на openCV java, чтобы определить, существует ли субимаг на большом изображении. Я хочу получить координаты соответствия только в том случае, если точный субимаж доступен на большом изображении. Я использую этот код, но получаю много ложных срабатываний. Прикрепленное изображение - это изображение и изображение большего размера. Растр нет в увеличения изображения, но я получаю матч на (873,715) larger imagesubimageШаблон, соответствующий ложному положительному

public void run(String inFile, String templateFile, String outFile, 
    int match_method) { 
    System.out.println("Running Template Matching"); 

    Mat img = Imgcodecs.imread(inFile); 
    Mat templ = Imgcodecs.imread(templateFile); 

    ///Create the result matrix 
    int result_cols = img.cols() - templ.cols() + 1; 
    int result_rows = img.rows() - templ.rows() + 1; 
    Mat result = new Mat(result_rows, result_cols, CvType.CV_32FC1); 

    ///Do the Matching and Normalize 
    Imgproc.matchTemplate(img, templ, result, match_method); 
    // Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new 
    // Mat()); 
    Imgproc.threshold(result, result, 0.1, 1.0, Imgproc.THRESH_TOZERO); 
    ///Localizing the best match with minMaxLoc 
    MinMaxLocResult mmr = Core.minMaxLoc(result); 

    Point matchLoc; 
    if (match_method == Imgproc.TM_SQDIFF 
      || match_method == Imgproc.TM_SQDIFF_NORMED) { 
     matchLoc = mmr.minLoc; 
    } else { 
     matchLoc = mmr.maxLoc; 
    } 
    double threashhold = 1.0; 
    if (mmr.maxVal > threashhold) { 
     System.out.println(matchLoc.x+" "+matchLoc.y); 
     Imgproc.rectangle(img, matchLoc, new Point(matchLoc.x + templ.cols(), 
       matchLoc.y + templ.rows()), new Scalar(0, 255, 0)); 
    } 
    // Save the visualized detection. 
    Imgcodecs.imwrite(outFile, img); 
} 

ответ

0

Я не знаком с OpenCV в Java, но OpenCV C++.

Я не думаю, что следующий код необходим.

Imgproc.threshold(result, result, 0.1, 1.0, Imgproc.THRESH_TOZERO); 

Значения min/max 'Mat result' будут между -1 и 1, если вы используете нормированную опцию. Поэтому ваш следующий код не будет работать, потому что ваш порог равен 1.0, если вы используете стандартизованный параметр.

if (mmr.maxVal > threshold) 

Кроме того, если вы используете CV_TM_SQDIFF, выше код должен быть

if (mmr.minVal < threshold) 

с правильным порогом.

Как насчет чертежа minMaxLoc перед сравнением minVal/maxVal с порогом? видеть, что он дает правильный результат? потому что матч в (873 715) смехотворный.