2016-09-22 4 views
2

Ich versuche, ein Stück Code über OpenCV Java zu laufen, dann übergeben Sie das Mat-Objekt an OpenCV JNI-Code, der Canny Edge-Erkennung auf und gibt die Mat zurück. Aber irgendwie bin ich immer wieder eine SIGSEGV bekommen, wenn die App startet und ich bin nicht sicher, warum das so ist:SIGSEGV auf OpenCV JNI von Android

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) 

Das Java-Code-Segment in Frage:

@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; 
} 

Der JNI-Code ist:

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; 
    } 
} 

Eine Idee, warum das passiert? Ich habe die bessere Hälfte des Tages damit verbracht, herauszufinden, warum das so ist, aber ich machte keinen anderen Weg als die problematischen Aussagen zu isolieren.

EDIT: Aus den Kommentaren

Ich denke, es war ein Fehler bei der Initialisierung von mCanny. Wenn ich den JNI-Anruf zu Canny ändere (* blur, * blur, 10, 30, 3); und dann in Java zurück mGauss anstelle von mCanny dann funktioniert es gut. Dies behebt es für den Moment, aber ich bin ehrlich gesagt immer noch nicht sicher, warum mCanny die SIGSEGV verursacht.

+0

Nach der Sigsegv-Fehlermeldung sollte ein Stack-Trace in logischer Folge gedruckt werden. Versuchen Sie, den Filter in logcat auf "No filters" zu ändern, und lassen Sie uns wissen, ob in der Ausgabe ein Stack-Trace angezeigt wird. –

+0

Die Spur ist: 09-23 01: 45: 32.911 442-442 /? I/DEBUG: Backtrace: 09-23 01: 45: 32.911 442-442 /? I/DEBUG: # 00 pc 00008230 /data/app/com.example.opencv.opencvtest-2/lib/arm/libgauss.so (Java_navin_tuts_opencv_opencvtest_MainActivity_nativeCanny + 39) 09-23 01: 45: 32.911 442-442 /? I/DEBUG: # 01 pc 0001082b /data/data/com.example.opencv.opencvtest/cache/slice-slice_4-classes.dex 39. Zeile ist die Unschärfe = (cv :: Mat *) iAddr; Zeile oben gezeigt – navinpai

Antwort

1

SEGV bedeutet, dass Sie versucht haben, nicht zugewiesenen Speicher zu lesen/schreiben. Die Fehleradresse ist 3. Etwas, das nahe bei 0 liegt, bedeutet fast immer, dass Sie einen Nullzeiger dereferenziert haben. Meine Vermutung ist, dass entweder mGauss oder mCanny eine 0 für ihr natives Objekt addr hatte.

+0

Überprüfte die Werte mit einem Debugger, und sie zeigen -1420884552 und -1420884432. Bedeutet das, dass sie Müllwerte bekommen? – navinpai

+0

Keiner von denen scheint schlecht - es ist möglich, dass es etwas weiter in Ihrem C-Code ist. Die Tatsache, dass eine Null in C dereferenziert wurde, ist jedoch ziemlich sicher. –

+1

Ich denke, es war ein Fehler bei der Initialisierung von mCanny. Wenn ich den JNI-Anruf zu Canny ändere (* blur, * blur, 10, 30, 3); und dann in Java zurück mGauss anstelle von mCanny dann funktioniert es gut. Dies behebt es für den Moment, aber ich bin ehrlich gesagt immer noch unsicher, warum mCanny die SIGSEGV verursacht! – navinpai