Opencv 将 Mat 从 Android 传递给 JNI 错误

Opencv passing Mat from Android to JNI error

我查阅了所有内容,但我不明白为什么我会收到致命信号 11。

Java 边:

mRgba = inputFrame.rgba();

String nativeTesting = mNativeDetector.getFeatures(mRgba);
Log.e(TAG, nativeTesting);    

// In another class
public String getFeatures(Mat image) {
    Log.e("FRAME", " Rows:" +image.rows());    // This correctly returns the number of rows
    String resultMsg = nativeFeatures(mNativeObj, image.getNativeObjAddr());
    return resultMsg;
}

C++ 端:

JNIEXPORT jstring JNICALL Java_com_example_myfacedetection_DetectionBasedTracker_nativeFeatures (JNIEnv* env, jclass, jlong image){

LOGD("NativeFeatures enter");

try {
    Mat* frame = (Mat*) image;
//        if (frame.empty())              // This also results in Fatal Signal
//            LOGD("EMPTY FRAME");


    LOGD("Size: %d", frame->rows);
}
catch(cv::Exception& e)
{
    LOGD("nativeCreateObject caught 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 (env)->NewStringUTF("Hello from JNI !");
}

我正在尝试计算直方图,但对帧的任何访问都会导致 SegFault。我做错了什么?

问题

这里最有可能的问题是您在 Java 中的本机方法声明(您尚未列出)与 JNI 库中的签名不匹配。

您正在调用它:

String resultMsg = nativeFeatures(mNativeObj, image.getNativeObjAddr())

所以你可能有(否则 javac 无法编译):

static native String nativeDetect(long thiz, long image);

但是在您的 JNI 库中您有:

JNIEXPORT jstring JNICALL Java_{snip}_nativeFeatures (JNIEnv* env, jclass, jlong image)

因此您将 mNativeObj 传递给 image,将其转换为 Mat 并在实际尝试跟随指针时获取 SIGSEGV。

解决方案

要解决此问题,请更新方法签名以匹配。例如,如果您不需要访问实例,请将静态方法设为 nativeDetect(long image)(并且不要将 mNativeObj 传递给它)。

备注

您有责任确保方法签名在您的 Java 和 C/C++ 源文件之间匹配。 Unless you have overloaded the native method (two signatures for the same name), the dynamic library loader is only looking for Java_{packageName}_{className}_{methodName} 并且无法判断参数数量或类型不匹配。