错误:从jni函数

时间:2017-02-01 10:11:58

标签: android opencv android-ndk sigsegv

我正在使用openCV处理相机,并尝试首先找到轮廓然后在图像上绘制轮廓来扫描文档。但是当我尝试从jni函数返回float[]时,我收到此错误。如果我的jni函数的返回类型无效,我的应用程序正常工作

日志条目:

D/Scanner: OpenCV library found inside package. Using it!
I/Scanner: onManagerConnected
D/CameraBridge: call checkCurrentState
D/ActivityThreadInjector: clearCachedDrawables.
D/Fabric: Using AdvertisingInfo from Service Provider
D/CameraBridge: call surfaceChanged event
D/CameraBridge: call checkCurrentState
D/CameraBridge: call processExitState: 0
D/CameraBridge: call processEnterState: 1
D/CameraBridge: call onEnterStartedState
D/JavaCameraView: Connecting to camera
D/JavaCameraView: Initialize java camera
D/JavaCameraView: Trying to open camera with old open()
D/JavaCameraView: getSupportedPreviewSizes()
D/JavaCameraView: Set preview size to 1920x1080
D/JavaCameraView: startPreview
I/art: Background partial concurrent mark sweep GC freed 42524(4MB) AllocSpace objects, 19(364KB) LOS objects, 40% free, 29MB/49MB, paused 5.552ms total 28.751ms
D/JavaCameraView: Starting processing thread
A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 7104 (Thread-8360)

我在某处读到大多数设备在硬件加速方面都不能很好地工作,所以我在清单文件中禁用它。即使在禁用硬件加速后,我也会遇到同样的错误。

清单文件

<activity android:name=".MainActivity"
    android:screenOrientation="landscape"
    android:configChanges="keyboardHidden|orientation"
    android:hardwareAccelerated="false">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

onCameraFrame方法(MainActivity.java)

@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
    rgba = inputFrame.rgba();
    // Finding contours that represents the piece of paper being scanned
    float[] points = ScannerNative.drawContours(rgba.getNativeObjAddr());
    if(points.length == 8){
        Log.d(TAG,"" + points[0] + "x" + points[4]);
        Log.d(TAG,"" + points[1] + "x" + points[5]);
        Log.d(TAG,"" + points[2] + "x" + points[6]);
        Log.d(TAG,"" + points[3] + "x" + points[7]);
    }

    return rgba;
}

ScannerNative.java

public class ScannerNative {
    public native static float[] drawContours(long matAddrRgba);
}

Jni功能

JNIEXPORT jfloatArray JNICALL Java_aac_scanner_ScannerNative_drawContours(JNIEnv *env, jclass thiz, jlong addrRgba){

    Mat& rgba = *(Mat*) addrRgba;
    Mat gray = rgba.clone();
    Mat canny = rgba.clone();

    vector< vector<Point> > contours;
    vector<Vec4i> hierarchy;
    vector<Point> approx, approxCurves;

    double area,maxArea=0.0,epsilon;

    cvtColor(rgba, gray, CV_RGBA2GRAY);
    GaussianBlur(gray, gray, Size(5,5), 0, 0);
    Canny(gray,canny,75,200);
    findContours( canny, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );

    canny.release();
    gray.release();

    for(int i=0;i<contours.size();i++){
        area = contourArea(contours[i]);
        epsilon = arcLength(contours[i], true)*0.02;
        approxPolyDP(contours[i], approxCurves, epsilon, true);

        if(area > maxArea && approxCurves.size() == 4 && fabs(area) > 1000 && isContourConvex(Mat(approx))){
            maxArea = area;
            approx = approxCurves;
        }
    }

    contours.erase(contours.begin(),contours.end());
    contours.push_back(approx);
    drawContours(rgba,contours,-1, Scalar(0,255,0), 2);

    jfloatArray jArray = env->NewFloatArray(8);
    if (jArray != NULL) {
        jfloat *ptr = env->GetFloatArrayElements(jArray, NULL);

        for (int i=0,j=i+4; j<8; i++,j++) {
            ptr[i] = approx[i].x;
            ptr[j] = approx[i].y;
        }
        env->ReleaseFloatArrayElements(jArray, ptr, NULL);
    }

    if(maxArea != 0.0) {
        LOGD("returnig array of points");
        return jArray;
    }
    else {
        LOGD("returnig 0");
        return 0;
    }
}

0 个答案:

没有答案