来自Android

时间:2016-09-22 19:22:51

标签: android c++ opencv android-ndk java-native-interface

我试图通过OpenCV Java运行一段代码,然后将Mat对象传递给OpenCV JNI代码,该代码对其执行Canny Edge检测并返回Mat。但不知何故,我在应用程序启动时反复收到SIGSEGV并且我不确定为什么会这样:

09-23 00:30:19.501 20399-20547/com.example.opencv.opencvtest A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x3 in tid 20547 (Thread-7450)

有问题的Java代码段是:

@Override
public void onCameraViewStarted(int width, int height) {
    // Everything initialized 
    mGray = new Mat(height, width, CvType.CV_8UC4);
    mGauss = new Mat(height, width, CvType.CV_8UC4);
    mCanny = new Mat(height, width, CvType.CV_8UC4);
}    

@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
    mGray = inputFrame.rgba();
    Imgproc.GaussianBlur(mGray, mGauss, new Size(), 5);

    // This works perfectly fine
    // Imgproc.Canny(mGauss, mCanny, 0, 20);

    // But this causes a SIGSEGV
    nativeCanny(mGauss.getNativeObjAddr(), mCanny.getNativeObjAddr());
    return mCanny;
}

JNI代码是:

 extern "C" {
 JNIEXPORT jboolean JNICALL
 Java_com_example_opencv_opencvtest_MainActivity_nativeCanny(JNIEnv *env, jobject instance, long iAddr, long oAddr) {

    cv::Mat* blur = (cv::Mat*) iAddr;
    cv::Mat* canny = (cv::Mat*) oAddr;

    // This line is causing the SIGSEGV because if I comment it, 
    // everything works (but Mat* canny is empty so shows up black screen)
    Canny(*blur, *canny, 10, 30, 3 );

    return true;
  }
}

知道为什么会这样吗?我花了一半时间试图弄清楚为什么会破裂,但除了隔离有问题的陈述之外没有取得任何进展。

编辑:来自评论

我认为mCanny的初始化是一个错误。如果我将JNI调用更改为Canny(* blur,* blur,10,30,3);然后在Java中返回mGauss而不是mCanny然后它工作正常。这暂时解决了这个问题,但老实说我还是不确定为什么mCanny会导致SIGSEGV。

1 个答案:

答案 0 :(得分:1)

SEGV意味着您尝试读取/写入未分配的内存。故障地址为3.接近0的东西几乎总是意味着你取消引用了一个空指针。我的猜测是mGauss或mCanny的本机对象地址为0。