'OpenCV Android React Native unknown exception on some functions in imgproc module
I'm trying to use OpenCV in an mobile app written with React Native. For now i only focus on the Android part. I use the official OpenCV for Android release. I did add the sdk, modified my MainApplication.java
and wrote some wrapping methods that can be called from React Native. So far this compiles and works as expected.
Now the problem is that if get an unknown exception
from some OpenCV functions, others work fine. E.g. when I call the blur()
, medianBlur()
or warpAffine()
functions from the Imgproc
module everything is well. When i try to call e.g. the gaussianBlur()
or Canny()
functions i get an unknown exception
thrown from OpenCV.
I really have no idea what the problem is. The sdk seems to be linked correctly as i can booth compile the app and run several functions.
My Setup:
- Development on Arch Linux
- OpenCV 4.3.0 for Android
- React Native 0.62.2
- Compiled with gradle/react-native from terminal
- Android 10
Example error when i try to run the Canny()
function:
org.opencv.imgproc: imgproc::Canny_12() caught unknown exception
unknown exception
java.lang.Exception: unknown exception
at org.opencv.imgproc.Imgproc.Canny_2(Native Method)
at org.opencv.imgproc.Imgproc.Canny(Imgproc.java:2662)
at com.rnopencv.RNOpenCvLibraryModule.cannyEdges(RNOpenCvLibraryModule.java:110)
at java.lang.reflect.Method.invoke(Native Method)
at com.facebook.react.bridge.JavaMethodWrapper.invoke(JavaMethodWrapper.java:372)
at com.facebook.react.bridge.JavaModuleWrapper.invoke(JavaModuleWrapper.java:151)
at com.facebook.react.bridge.queue.NativeRunnable.run(Native Method)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27)
at android.os.Looper.loop(Looper.java:214)
at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:226)
at java.lang.Thread.run(Thread.java:919)
calling the following wrapper:
@ReactMethod
public void cannyEdges(String imageAsBase64, int treshold, Promise promise) {
try {
// Constants
Size BLUR_SIZE = new Size(3,3);
int KERNEL_SIZE = 3;
int RATIO = 3;
int MAX_LOW_THRESHOLD = 100;
int lowTreshold = (treshold <= MAX_LOW_THRESHOLD) ? treshold : MAX_LOW_THRESHOLD;
// decode base64 string to matrix
Bitmap srcImage = base64ImageToBitmap(imageAsBase64);
Mat srcMat = new Mat();
Utils.bitmapToMat(srcImage, srcMat);
// rotate image to be portrait
Mat orientedMat = rotateBoxed(srcMat, -90);
// blur the image
Mat bluredMat = new Mat();
Mat cannyMat = new Mat();
Imgproc.blur(orientedMat, bluredMat, BLUR_SIZE);
// NEXT LINE THROWS THE ERROR
Imgproc.Canny(bluredMat, cannyMat, lowTreshold, lowTreshold * RATIO, KERNEL_SIZE, false);
// return blured image wrapped in promise
Bitmap dstImage = Bitmap.createBitmap(cannyMat.cols(), cannyMat.rows(), srcImage.getConfig());
Utils.matToBitmap(cannyMat, dstImage);
promise.resolve(bitmapToBase64(dstImage));
} catch (Exception e) {
System.out.println("Oh snap, some Exception occured!");
System.out.println(e.getMessage());
e.printStackTrace(System.out);
promise.reject("Could not perform canny edge detection on image!", e);
}
}
The wrapper gets the image as base64 encoded String (don't have a better solution yet) and returns the result in a js Promise. I also rotate the image to correct orientation using an affine transformation (this part works like described above). I tried various values for threshold, same goes for the gaussianBlur() method. The result is always either an assertion failure for invalid parameters (which is expected) or the mysterious unknown exception.
Any clues on what the problem might be?
Update: When i use an older version of openCV e.g. 3.4.10 for Android it will work.
Solution 1:[1]
At last time, I faced this problem, so I chose Open CV API instead of this. I hope this help you a bit.
Solution 2:[2]
I have been working without error on opencv 4.5.2, android and react native. Than i have tried another project with same opencv version but I got same error as you mentioned. Than i realized differences between gradle version. So, i upgraded gradle version from "com.android.tools.build:gradle:3.5.2" to "com.android.tools.build:gradle:4.2.2" in app gradle.build file. Than problem solved. Long story short, update gradle version.
I hope that helps you too.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Angel Jerry |
Solution 2 | Canberk Atbinici |