3

I am trying to use OpenCV (java) to do template matching and use the max min values to determine whether the object found or not.

I am using the following java/opencv code but the problem is it returns 0.0 for min values for both best match as well as for the scenarios where no match found.

So this template matching seems unreliable to determine whether the object found or not. Am I doing anything wrong in this code or I need to go for any other techniques?

Thanks in advance.

    int templateMatchMethod = Imgproc.TM_SQDIFF_NORMED;
    Mat largeImage = Highgui.imread(largeUrl);
    Mat smallImage = Highgui.imread(smallUrl);

    boolean isMaxTypleMethod = true;

    double TEMPLATE_MATCH_THRESHOLD = 0.8;

    int result_cols = largeImage.cols() - smallImage.cols() + 1;
    int result_rows = largeImage.rows() - smallImage.rows() + 1;
    Mat result = new Mat(result_rows, result_cols, CvType.CV_8U);

    Imgproc.matchTemplate(largeImage, smallImage, result, templateMatchMethod);
    Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());

    MinMaxLocResult mmr = Core.minMaxLoc(result);

    Point matchLoc;
    double minMaxValue = 1;
    if (templateMatchMethod == Imgproc.TM_SQDIFF || templateMatchMethod == Imgproc.TM_SQDIFF_NORMED)
    {
        matchLoc = mmr.minLoc;
        isMaxTypleMethod = false;
        TEMPLATE_MATCH_THRESHOLD = 0.4;
        minMaxValue = mmr.minVal;
    }
    else
    {
        matchLoc = mmr.maxLoc;
        minMaxValue = mmr.maxVal;
    }

    Core.rectangle(largeImage, matchLoc, new Point(matchLoc.x + smallImage.cols(),
            matchLoc.y + smallImage.rows()), new Scalar(0, 255, 0));

    System.out.println("minMaxValue : "+minMaxValue);
    if(isMaxTypleMethod && TEMPLATE_MATCH_THRESHOLD < minMaxValue)
    {
        System.out.println("Match found");
    }
    else if (!isMaxTypleMethod && TEMPLATE_MATCH_THRESHOLD > minMaxValue)
    {
        System.out.println("Match found");
    }
Emily Webb
  • 325
  • 2
  • 6
  • 16

2 Answers2

4

this looks pretty suspicious:

Mat result = new Mat(result_rows, result_cols, CvType.CV_8U);  // better use CvType.CV_32F here

Imgproc.matchTemplate(largeImage, smallImage, result, templateMatchMethod);
Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());   // normalizing a uchar mat into [0..1] can only result in garbage.

again, it will work much nicer, if you use float type for result and skip the normalize

berak
  • 39,159
  • 9
  • 91
  • 89
  • Wow,that made a big difference. But seems like I have to be more strict when choosing threshold it seems. A best match value was 8.158945711329579E-4 (E-4 which is really awesome) while another object which is no way related to the large image returned a min value of 0.0739038735628128. Well how can the non related image can give such a low value like 0.07? again is there anything has to be corrected? or it's normal and I just wanted to have a strict threshold like 0.001 ? – Emily Webb Jul 27 '13 at 11:25
  • This only happens to certain types of images while most of other unrelated images give reasonable a minvalue like 0.45 etc. – Emily Webb Jul 27 '13 at 12:40
0

Dont normalize the result, i mean remove this line from your code,

    Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());   // normalizing a uchar mat into 

this will work fine and will give you the proper value of minmax,

Mehul Thakkar
  • 12,440
  • 10
  • 52
  • 81