SIGSEGV on OpenCV JNI from Android

SIGSEGV on OpenCV JNI from Android

本文关键字:from Android JNI OpenCV on SIGSEGV      更新时间:2023-10-16

我试图通过OpenCV Java运行一段代码,然后将Mat对象传递给OpenCV JNI代码,该代码对其进行Canny边缘检测并返回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。

SEGV表示您试图读取/写入未分配的内存。故障地址为3。接近0的值几乎总是意味着对空指针解引用。我猜mGauss或mCanny的原生对象addr都是0