1

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?

piotrek
  • 13,982
  • 13
  • 79
  • 165
  • As far as I can see in [the documentation](https://docs.opencv.org/java/2.4.2/org/opencv/core/Core.html#minMaxLoc(org.opencv.core.Mat)) it should be something like `result = minMaxLoc(normalizedResult);` and result is type `Core.MinMaxLocResult` or maybe it is a different OpenCV version? – api55 Aug 02 '18 at 13:38
  • it's javacpp-presets: a java wrapper for c++. so the API imitates c++ API. this method returns void – piotrek Aug 02 '18 at 13:45
  • I see, I have never worked with it. Anyways, there is a high chance that minVal and maxVal are pointers pointing to not a double, but something like nullptr in C++ and maybe it requires to be initialized/allocated somehow. In the documentation it seems that is the case... maybe you can try with `new DoublePointer(1)`. Which allocates 1 double for this pointer – api55 Aug 02 '18 at 14:15
  • yep, seems like that's the problem. add the answer, ill accept – piotrek Aug 02 '18 at 15:07

1 Answers1

1

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.

api55
  • 11,070
  • 4
  • 41
  • 57