javaopencvimage-processingtemplate-matchingjavacpp

OpenCV: minMaxLoc gives no min / max value


I'm trying to follow OpenCV tutorial on image template matching using javacpp-presets. I want to throw away matches with too low score but minMaxLoc seems to not return minVal and maxVal.

import org.bytedeco.javacpp.DoublePointer;
import org.bytedeco.javacpp.opencv_core.Mat;
import org.bytedeco.javacpp.opencv_core.Point;

import static org.bytedeco.javacpp.opencv_core.CV_32FC1;
import static org.bytedeco.javacpp.opencv_core.NORM_MINMAX;
import static org.bytedeco.javacpp.opencv_core.minMaxLoc;
import static org.bytedeco.javacpp.opencv_core.normalize;
import static org.bytedeco.javacpp.opencv_imgcodecs.IMREAD_COLOR;
import static org.bytedeco.javacpp.opencv_imgcodecs.imread;
import static org.bytedeco.javacpp.opencv_imgproc.TM_CCOEFF_NORMED;
import static org.bytedeco.javacpp.opencv_imgproc.matchTemplate;

public class MatchTemp {

    public static void match(String img, String temp) {

        Mat image = imread(img, IMREAD_COLOR);
        Mat template = imread(temp, IMREAD_COLOR);

        int resultRows = image.rows() - template.rows() + 1;
        int resultCols = image.cols() - template.cols() + 1;
        Mat result = new Mat(resultRows, resultCols, CV_32FC1);

        matchTemplate(image, template, result, TM_CCOEFF_NORMED);

        Mat normalizedResult = new Mat();
        normalize(result, normalizedResult, 0, 1, NORM_MINMAX, -1, new Mat());

        DoublePointer maxVal = new DoublePointer();
        DoublePointer minVal = new DoublePointer();
        Point minLoc = new Point();
        Point maxLoc = new Point();

        minMaxLoc(normalizedResult, minVal, maxVal, minLoc, maxLoc, null);

        System.out.println("min: "+minLoc.x()+", "+minLoc.y());
        System.out.println("max: "+maxLoc.x()+", "+maxLoc.y());

        minVal.get(); // this throws exception
        maxVal.get(); // this throws exception
    }
}

The exception is:

Exception in thread "main" java.lang.NullPointerException: This pointer address is NULL.
    at org.bytedeco.javacpp.DoublePointer.get(Native Method)
    at org.bytedeco.javacpp.DoublePointer.get(DoublePointer.java:101)
    ...

What am i doing wrong? How can i get the score? Do i have to manually check the content of the Mat?


Solution

  • The error tells you that it is trying to access a Null reference. Reading the documentation of DoublePointer constructor which tells to look at Pointer.Pointer() it basically tells you the following:

    Default constructor that does nothing.

    This means that it is just a pointer similar to C++:

    double *p;
    

    Which does not point to any double, but the documentation tells you that there is another constructor for DoublePointer

    public DoublePointer(long size)
    

    which says that it allocates an array of this size. If size is equal to 1 it is equivalent to say in C++ this is equivalent to:

    double p[1];
    

    or basically

    double *p = new double;
    

    I have never used JavaCpp so if I missed something, please do comment.