Android Java Dnn.forward multiple output layers -> segmentation fault

asked 2019-06-24 05:32:19 -0600

Hello all,

I want to run a yolov3-tiny darknet model on an android device using opencv. that yolo model has 2 output layers named "yolo_16" and "yolo_23". When i try to run the model with either one of these layers as output the code works as expected:

net.forward(outputs, "yolo_16")

but when i try to get both layers in one call like in these examples

i get a segmentation fault error like this:

Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 5691 (Thread-8)


the opencv version is 3.4.3 installed according to these instructions on android studio.

a reduced version of the code that i use is here:

public class MainActivity extends AppCompatActivity implements CvCameraViewListener2 {

    private Mat                  mRgba;
    private Net                  net;
    private List<String>         ln;
    private CameraBridgeViewBase mOpenCvCameraView;

    private BaseLoaderCallback  mLoaderCallback = new BaseLoaderCallback(this) {
        @Override public void onManagerConnected(int status) {
            if (status == LoaderCallbackInterface.SUCCESS) { mOpenCvCameraView.enableView(); }
            else { super.onManagerConnected(status); }
        }
    };

    @Override public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, 200);
            return;
        }

        mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.color_blob_detection_activity_surface_view);
        mOpenCvCameraView.setMaxFrameSize(720, 720);
        mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
        mOpenCvCameraView.setCvCameraViewListener(this);
    }

    public void onCameraViewStarted(int width, int height) {
        mRgba = new Mat(height, width, CvType.CV_8UC4);
        net = Dnn.readNetFromDarknet(getFile("yolov3-tiny.cfg", this), getFile("yolov3-tiny.weights", this));
        ln = getOutputNames(net);

    }
    public void onCameraViewStopped() {
        mRgba.release();
    }

    public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
        mRgba = inputFrame.rgba();

        Imgproc.cvtColor(mRgba, mRgba, Imgproc.COLOR_RGBA2RGB);
        Mat inputBlob = Dnn.blobFromImage(mRgba, 1.0, new Size(416,416), new Scalar(0), false, false);

        net.setInput(inputBlob);
        List<Mat> output = new ArrayList<Mat>();

        net.forward(output, ln);

        inputBlob.release();
        return mRgba;
    }

    @Override public void onPause() {
        super.onPause();
        if (mOpenCvCameraView != null) { mOpenCvCameraView.disableView(); }
    }

    @Override public void onResume() {
        super.onResume();
        if (!OpenCVLoader.initDebug()) { OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback); }
        else { mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS); }
    }

    public void onDestroy() {
        super.onDestroy();
        if (mOpenCvCameraView != null) { mOpenCvCameraView.disableView(); }
    }



    private static MatOfByte getFile(String file, Context context) {
        AssetManager assetManager = context.getAssets();
        BufferedInputStream inputStream = null;
        try {
            // Read data from assets.
            inputStream = new BufferedInputStream(assetManager.open(file));
            byte[] data = new byte[inputStream.available()];
            inputStream.read(data);
            inputStream.close();

            return new MatOfByte(data);
        } catch (IOException ex) { }
        return new MatOfByte();
    }

    private static List<String> getOutputNames(Net net) {
        List<String> names = new ArrayList<>();

        List<Integer> outLayers = net.getUnconnectedOutLayers().toList();
        List<String> layersNames = net.getLayerNames();

        outLayers.forEach((item) -> names.add(layersNames.get(item - 1)));
        return names;
    }

and the full error is here:

Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 5691 (Thread-8)

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'HUAWEI/ANE-LX1/HWANE:8.0.0/HUAWEIANE-LX1/178(C432):user/release-keys'
Revision: '0'
ABI: 'arm64'
pid: 5634, tid: 5691, name: Thread-8  >>> com.example.opencv_yolo <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
Cause: null pointer dereference
    x0   0000000000000000  x1   0000000000000000  x2   0000000000000000  x3   0000000000000000
    x4   000000742cf09380  x5   0000000000000000  x6   000000743b66b3c0  x7   0000000000000000
    x8   34b0d45095ce85c8  x9   34b0d45095ce85c8  x10  000000000000006b ...
(more)
edit retag flag offensive close merge delete

Comments

any chance you can update your opencv libs ?

(there was a bug with List<String> related to processing yolo networks in 3.4.3)

berak gravatar imageberak ( 2019-06-25 00:34:50 -0600 )edit