Ask Your Question

Revision history [back]

If someone has the same problem than me, my solution was to edit the Python script which generates the C++ and Java code of the JNI binding: modules/java/generator/gen_java.py.

I added the following code after the declaration of minMaxLoc: line 413, after }, # minMaxLoc

'minMaxIdx' : {
            'j_code'   : """
    // manual port
    public static class MinMaxIdxResult {
        public double minVal;
        public double maxVal;

        public MinMaxIdxResult() {
            minVal=0; maxVal=0;
        }
    }

    // C++: minMaxIdx(Mat src, double* minVal, double* maxVal=0, int* minIdx=0, int* maxIdx=0, InputArray mask=noArray())

    //javadoc: minMaxIdx(src, mask)
    public static MinMaxIdxResult minMaxIdx(Mat src, MatOfInt minIdx, MatOfInt maxIdx, Mat mask) {
        MinMaxIdxResult res = new MinMaxIdxResult();
        long minIdxNativeObj=0;
        if (minIdx != null) {
            minIdxNativeObj=minIdx.nativeObj;
        }
        long maxIdxNativeObj=0;
        if (maxIdx != null) {
            maxIdxNativeObj=maxIdx.nativeObj;
        }
        long maskNativeObj=0;
        if (mask != null) {
            maskNativeObj=mask.nativeObj;
        }
        double resarr[] = n_minMaxIdxManual(src.nativeObj, minIdxNativeObj, maxIdxNativeObj, maskNativeObj);
        res.minVal=resarr[0];
        res.maxVal=resarr[1];
        return res;
    }

    //javadoc: minMaxIdx(src, minIdx, maxIdx)
    public static MinMaxIdxResult minMaxIdx(Mat src, MatOfInt minIdx, MatOfInt maxIdx) {
        return minMaxIdx(src, minIdx, maxIdx, null);
    }

    //javadoc: minMaxIdx(src, minIdx)
    public static MinMaxIdxResult minMaxIdx(Mat src, MatOfInt minIdx) {
        return minMaxIdx(src, minIdx, null, null);
    }

    //javadoc: minMaxIdx(src)
    public static MinMaxIdxResult minMaxIdx(Mat src) {
        return minMaxIdx(src, null, null, null);
    }

""",
            'jn_code'  :
"""    private static native double[] n_minMaxIdxManual(long src_nativeObj, long minIdx_nativeObj, long maxIdx_nativeObj, long mask_nativeObj);\n""",
            'cpp_code' :
"""
// C++: minMaxIdx(Mat src, double* minVal, double* maxVal=0, int* minIdx=0, int* maxIdx=0, InputArray mask=noArray())
JNIEXPORT jdoubleArray JNICALL Java_org_opencv_core_Core_n_1minMaxIdxManual (JNIEnv*, jclass, jlong, jlong, jlong, jlong);

JNIEXPORT jdoubleArray JNICALL Java_org_opencv_core_Core_n_1minMaxIdxManual
  (JNIEnv* env, jclass, jlong src_nativeObj, jlong minIdx_nativeObj, jlong maxIdx_nativeObj, jlong mask_nativeObj)
{

    try {
        LOGD("Core::n_1minMaxIdx()");
        jdoubleArray result;
        result = env->NewDoubleArray(2);
        if (result == NULL) {
            return NULL; /* out of memory error thrown */
        }

        Mat& src = *((Mat*)src_nativeObj);

        double minVal, maxVal;
        int minIdx[src.dims];
        int maxIdx[src.dims];

        if (mask_nativeObj != 0) {
            Mat& mask = *((Mat*)mask_nativeObj);
            minMaxIdx(src, &minVal, &maxVal, minIdx, maxIdx, mask);
        } else {
            minMaxIdx(src, &minVal, &maxVal, minIdx, maxIdx);
        }

        if (minIdx_nativeObj != 0) {
            Mat& minIdx_mat = *((Mat*)minIdx_nativeObj);
            for(int i = 0; i < src.dims; i++) {
                minIdx_mat.at<int>(i) = minIdx[i];
            }
        }
        if (maxIdx_nativeObj != 0) {
            Mat& maxIdx_mat = *((Mat*)maxIdx_nativeObj);
            for(int i = 0; i < src.dims; i++) {
                maxIdx_mat.at<int>(i) = maxIdx[i];
            }
        }

        jdouble fill[2];
        fill[0]=minVal;
        fill[1]=maxVal;

        env->SetDoubleArrayRegion(result, 0, 2, fill);

    return result;

    } catch(const cv::Exception& e) {
        LOGD("Core::n_1minMaxIdx() catched cv::Exception: %s", e.what());
        jclass je = env->FindClass("org/opencv/core/CvException");
        if(!je) je = env->FindClass("java/lang/Exception");
        env->ThrowNew(je, e.what());
        return NULL;
    } catch (...) {
        LOGD("Core::n_1minMaxIdx() catched unknown exception (...)");
        jclass je = env->FindClass("java/lang/Exception");
        env->ThrowNew(je, "Unknown exception in JNI code {core::minMaxIdx()}");
        return NULL;
    }
}

""",
        }, # minMaxIdx

This code could be greatly improved by merging the structures MinMaxLocResult and MinMaxIdxResult, but I didn't want to change the code of minMaxLoc.