Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

OpenCV on Android: net.forward yields "blobs.size() >= 2" Assertion failed

Following this tutorial from openCV, and it should be straight forward. However, it crashes with an assertion fail on the net.forward, that I cannot resolve/find anywhere else.

Thought this problem seemed similar and tried to go through the fix/problem finding. However, restarting the discussion and trials showed it is likely not the same. I used initially 3.4.3, which did not support the same Mat type somehow. Updated to 3.4.7 now, and can confirm the blob size is okay (generated from image). Tried also various other prototxt and caffemodels, but doubt by now that the problem lies there (works if the files are okay, otherwise the net loading fails). The key code should be this:

// Load a network.
public void onCameraViewStarted(int width, int height) {
    String proto = getPath("deploy.prototxt", this);
    String weights = getPath("MobileNetSSD_deploy.caffemodel", this);
    net = Dnn.readNetFromCaffe(proto, weights);
    Log.i(TAG, "Network loaded successfully");
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
    // Get a new frame
    Mat frame = inputFrame.rgba();
    Imgproc.cvtColor(frame, frame, Imgproc.COLOR_RGBA2RGB);
    // Forward image through network.
    Mat blob = Dnn.blobFromImage(frame, 0.007843,
            new Size(300, 300),
            new Scalar(127.5, 127.5, 127.5));

    net.setInput(blob);
    Mat detections = net.forward(); //***215 ASSERTION FAILED occurs***
    int cols = frame.cols();
    int rows = frame.rows();
    detections = detections.reshape(1, (int)detections.total() / 7);
    for (int i = 0; i < detections.rows(); ++i) {
        double confidence = detections.get(i, 2)[0];
        if (confidence > 0.2) {
            int classId = (int)detections.get(i, 1)[0];
            int left   = (int)(detections.get(i, 3)[0] * cols);
            int top    = (int)(detections.get(i, 4)[0] * rows);
            int right  = (int)(detections.get(i, 5)[0] * cols);
            int bottom = (int)(detections.get(i, 6)[0] * rows);
            // Draw rectangle around detected object.
            Imgproc.rectangle(frame, new Point(left, top), new Point(right, bottom),
                    new Scalar(0, 255, 0));
            String label = classNames[classId] + ": " + confidence;
            int[] baseLine = new int[1];
            Size labelSize = Imgproc.getTextSize(label, Core.FONT_HERSHEY_SIMPLEX, 0.5, 1, baseLine);
            // Draw background for label.
            Imgproc.rectangle(frame, new Point(left, top - labelSize.height),
                    new Point(left + labelSize.width, top + baseLine[0]),
                    new Scalar(255, 255, 255), Core.FILLED);
            // Write class name and confidence.
            Imgproc.putText(frame, label, new Point(left, top),
                    Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar(0, 0, 0));
        }
    }
    return frame;
}
public void onCameraViewStopped() {}
// Upload file to storage and return a path.
private static String getPath(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();
        // Create copy file in storage.
        File outFile = new File(context.getFilesDir(), file);
        FileOutputStream os = new FileOutputStream(outFile);
        os.write(data);
        os.close();
        // Return a path to file which may be read in common way.
        return outFile.getAbsolutePath();
    } catch (IOException ex) {
        Log.i(TAG, "Failed to upload a file");
    }
    return "";
}

The full error message is

cv::Exception: OpenCV(3.4.7) /build/3_4_pack-android/opencv/modules/dnn/src/layers/batch_norm_layer.cpp:39: error: (-215:Assertion failed) blobs.size() >= 2 in function 'cv::dnn::BatchNormLayerImpl::BatchNormLayerImpl(const cv::dnn::experimental_dnn_34_v13::LayerParams&)'

I expect it to not crash. The frame should be okay (image loaded), the net is not empty, and the layers in the net seem fine too (checked since there are some differences using caffe in java). Any help is appreciated!