bytedeco / javacv

Java interface to OpenCV, FFmpeg, and more
Other
7.41k stars 1.57k forks source link

java.lang.NullPointerException: This pointer address is NULL. #2111

Closed chankam1024 closed 8 months ago

chankam1024 commented 8 months ago

I have written two methods, one is to directly perform template matching; The second method is to first zoom and then perform template matching, because I want to achieve image matching at different resolutions. Method 1 runs normally and can be matched, but Method 2 keeps prompting NullPointerException: This pointer address is NULL. I don't know why. I hope you can help me. Thank you very much~ The following is the code.

public static void imgMatchTemplate() {
        Mat target = imread("C:\\Users\\Dream\\Desktop\\test\\target.png");
        Mat source = imread("C:\\Users\\Dream\\Desktop\\test\\source.png");
        // 创建输出结果的Mat对象
        Mat result = new Mat();
        // 进行模板匹配
        matchTemplate(source, target, result, TM_CCOEFF_NORMED);
        // 创建最佳匹配位置变量
        DoublePointer minVal = new DoublePointer();
        DoublePointer maxVal = new DoublePointer();
        Point minLoc = new Point();
        Point maxLoc = new Point();
        // 查找最佳匹配位置
        minMaxLoc(result, minVal, maxVal, minLoc, maxLoc, null);
        // 输出最佳匹配位置
        System.out.println("最佳匹配位置:(" + maxLoc.x() + ", " + maxLoc.y() + ")");
        // 绘制矩形框
        int width = target.cols();
        int height = target.rows();
        rectangle(source, maxLoc, new Point(maxLoc.x() + width, maxLoc.y() + height),
                new Scalar(0, 255, 0, 0), 2, 0, 0);
        // 保存带有矩形框的图像
        imwrite("C:\\Users\\Dream\\Desktop\\test\\result.png", source);
    }
public static void imgResizeMatchTemplate() {
        Mat target = imread("C:\\Users\\Dream\\Desktop\\test\\target.png");
        Mat source = imread("C:\\Users\\Dream\\Desktop\\test\\source.png");
        // 存储最佳匹配结果
        double bestMatchValue = 0;
        Point bestMatchLocation = new Point();
        // 循环缩放目标图进行匹配
        for (double scale = 0.5; scale <= 2.0; scale = NumberUtil.add(scale, 0.1)) {
            // 缩放目标图像
            Mat scaledTarget = new Mat();
            resize(target, scaledTarget, new Size(), scale, scale, INTER_LINEAR);
            Mat result = new Mat();
            matchTemplate(source, scaledTarget, result, TM_CCOEFF_NORMED);
            DoublePointer minVal = new DoublePointer();
            DoublePointer maxVal = new DoublePointer();
            Point minLoc = new Point();
            Point maxLoc = new Point();
            // 查找最佳匹配位置
            minMaxLoc(result, minVal, maxVal, minLoc, maxLoc, null);
            if (maxLoc.get() > bestMatchValue) { // Here is a hint of NullPointerException
                bestMatchValue = maxVal.get();
                bestMatchLocation = maxLoc;
            }
        }
        // 输出最佳匹配位置
        System.out.println("最佳匹配位置:(" + bestMatchLocation.x() + ", " + bestMatchLocation.y() + ")");
        // 绘制矩形框
        int width = target.cols();
        int height = target.rows();
        rectangle(source, bestMatchLocation, new Point(bestMatchLocation.x() + width, bestMatchLocation.y() + height),
                new Scalar(0, 255, 0, 0), 2, 0, 0);
        // 保存带有矩形框的图像
        imwrite("C:\\Users\\Dream\\Desktop\\test\\result.png", source);
    }
chankam1024 commented 8 months ago

JavaCV uses 1.5.9, OpenCV uses 4.7.0, and OpenBLAS uses 0.3.23. I tried not to perform scaling and template matching in the for loop, but still prompted for NullPointerException.

chankam1024 commented 8 months ago

Oh, I'm very sorry, I found an error in Method 2. Original code:

if (maxLoc.get() > bestMatchValue) {
    bestMatchValue = maxVal.get();
    bestMatchLocation = maxLoc;
}

New code:

if (maxVal.get() > bestMatchValue) {
    bestMatchValue = maxVal.get();
    bestMatchLocation = maxLoc;
}

I'm very sorry, the code I provided is incorrect and has been corrected, but there is still a NullPointerException.

chankam1024 commented 8 months ago

I tried to modify the code in Method 2, and although I don't know the reason, it can now run normally.Thank you very much!

double[] minVal = new double[1];
double[] maxVal = new double[1];
Point minLoc = new Point();
Point maxLoc = new Point();
// 查找最佳匹配位置
minMaxLoc(result, minVal, maxVal, minLoc, maxLoc, null);
if (maxVal[0] > bestMatchValue) {
    bestMatchValue = maxVal[0];
    bestMatchLocation = maxLoc;
}