首页 > 解决方案 > imgproc 模块中某些函数的 OpenCV Android React Native 未知异常

问题描述

我正在尝试在使用 React Native 编写的移动应用程序中使用 OpenCV。现在我只关注Android部分。我使用 Android 版的官方 OpenCV。我确实添加了 sdk,修改了我的MainApplication.java并编写了一些可以从 React Native 调用的包装方法。到目前为止,这可以按预期编译和工作。

现在的问题是,如果unknown exception从一些 OpenCV 函数中获取一个,其他的工作正常。例如,当我从模块调用blur(), medianBlur()orwarpAffine()函数时,Imgproc一切都很好。当我尝试调用例如gaussianBlur()orCanny()函数时,我会unknown exception从 OpenCV 抛出异常。

我真的不知道问题是什么。sdk 似乎链接正确,因为我可以编译应用程序并运行多个功能。

我的设置:

我尝试运行该Canny()函数时的示例错误:

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)

调用以下包装器:

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

包装器将图像作为 base64 编码的字符串(目前还没有更好的解决方案)并以 js Promise 的形式返回结果。我还使用仿射变换将图像旋转到正确的方向(这部分的工作原理如上所述)。我尝试了各种阈值值,gaussianBlur() 方法也是如此。结果总是无效参数的断言失败(这是预期的)或神秘的未知异常。

关于问题可能是什么的任何线索?

更新:当我使用旧版本的 openCV 例如 3.4.10 for Android 时,它会起作用。

标签: javaandroidreact-nativeopencv

解决方案


上次我遇到了这个问题,所以我选择了 Open CV API 而不是这个。我希望这对你有所帮助。


推荐阅读