Java Android,opencv-在尝试初始化Mat时,找不到long org.opencv.core.Mat.n_Mat()的实现

Java Android,opencv-在尝试初始化Mat时,找不到long org.opencv.core.Mat.n_Mat()的实现,java,android,opencv,gradle,dependencies,Java,Android,Opencv,Gradle,Dependencies,我想使用OpenCV做一些事情,我正在尝试创建Mat对象: import org.opencv.core.CvType; import org.opencv.core.Mat; ... Mat imageMat = new Mat(CvType.CV_8U); 在这一行,我得到一个错误: 2021-04-28 15:13:44.657 23613-23613/xxxx.yyyy E/art: No implementation found for long org.opencv.core.Ma

我想使用OpenCV做一些事情,我正在尝试创建
Mat
对象:

import org.opencv.core.CvType;
import org.opencv.core.Mat;
...
Mat imageMat = new Mat(CvType.CV_8U);
在这一行,我得到一个错误:

2021-04-28 15:13:44.657 23613-23613/xxxx.yyyy E/art: No implementation found for long org.opencv.core.Mat.n_Mat() (tried Java_org_opencv_core_Mat_n_1Mat and Java_org_opencv_core_Mat_n_1Mat__)
2021-04-28 15:13:44.676 23613-23613/xxxx.yyyy D/AndroidRuntime: Shutting down VM
2021-04-28 15:13:44.686 23613-23613/xxxx.yyyy E/AndroidRuntime: FATAL EXCEPTION: main
    Process: xxxx.yyyy, PID: 23613
    java.lang.UnsatisfiedLinkError: No implementation found for long org.opencv.core.Mat.n_Mat() (tried Java_org_opencv_core_Mat_n_1Mat and Java_org_opencv_core_Mat_n_1Mat__)
        at org.opencv.core.Mat.n_Mat(Native Method)
        at org.opencv.core.Mat.<init>(Mat.java:26)
        at org.opencv.core.MatOfPoint2f.<init>(MatOfPoint2f.java:12)
        at xxxx.yyyy.Utils.quadrilateralToRect(Utils.java:77)
        at xxxx.yyyy.activities.CropActivity$1.onClick(CropActivity.java:74)
        at android.view.View.performClick(View.java:5619)
        at android.view.View$PerformClick.run(View.java:22298)
        at android.os.Handler.handleCallback(Handler.java:754)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:165)
        at android.app.ActivityThread.main(ActivityThread.java:6375)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802)
在my
MainActivity.java
中。它打印“成功”,但错误尚未消失。然而,它改变了:

2021-04-28 21:09:47.798 22656-22656/xxxx.yyyy E/AndroidRuntime: FATAL EXCEPTION: main
    Process: xxxx.yyyy, PID: 22656
    java.lang.UnsupportedOperationException: Native object address is NULL
        at org.opencv.core.Mat.<init>(Mat.java:14)
        at xxxx.yyyy.Utils.quadrilateralToRect(Utils.java:94)
        at xxxx.yyyy.activities.CropActivity$1.onClick(CropActivity.java:74)
        at android.view.View.performClick(View.java:5619)
        at android.view.View$PerformClick.run(View.java:22298)
        at android.os.Handler.handleCallback(Handler.java:754)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:165)
        at android.app.ActivityThread.main(ActivityThread.java:6375)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802)
2021-04-28 21:09:47.798 22656-22656/xxxx.yyy E/AndroidRuntime:致命异常:main
进程:xxxx.yyyy,PID:22656
java.lang.UnsupportedOperationException:本机对象地址为NULL
在org.opencv.core.Mat.(Mat.java:14)
在xxxx.yyy.Utils.quadrilateralToRect(Utils.java:94)
在xxxx.yyy.activities.CropActivity$1.onClick(CropActivity.java:74)
在android.view.view.performClick上(view.java:5619)
在android.view.view$PerformClick.run(view.java:22298)
位于android.os.Handler.handleCallback(Handler.java:754)
位于android.os.Handler.dispatchMessage(Handler.java:95)
位于android.os.Looper.loop(Looper.java:165)
位于android.app.ActivityThread.main(ActivityThread.java:6375)
位于java.lang.reflect.Method.invoke(本机方法)
在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)上
位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802)
UPD 2


UPD 1中的Oops错误是由于
new Mat()
中的参数引起的。如果没有参数,则还没有错误。调查仍在继续。

似乎我已经找到了解决方案(为OpenCV 3工作)。需要将文件夹
sdk\native\libs
从下载的sdk复制到项目的根目录中,并将其命名为
jniLibs
。每个Forder都有一个名为
libopencv_java3.so
的文件,如下所示:

此外,将以下代码添加到您的主要活动中可能也很有用:

static {
    if (OpenCVLoader.initDebug()) {
        Log.d(TAG, "OPENCV INITIALIZATION SUCCEEDED");
    } else {
        Log.d(TAG, "OPENCV INITIALIZATION FAILED BUT TRYING TO RELOAD");
        System.loadLibrary("opencv_java3");
    }
}

坏的一面:这些文件在生成后会向APK添加80MB。欢迎提供更好的解决方案。

建议使用CMake链接SDK,而不是复制编译后的文件

您可以在应用程序build.gradle中的 android>defaultConfig>externalNativeBuild>cmake

arguments "-DOpenCV_DIR=" + file('../sdk').absolutePath + "/native/jni",
        "-DANDROID_TOOLCHAIN=clang",
        "-DANDROID_STL=c++_shared"
然后使用find_包在CMake中安装OpenCV

set(ANDROID_OPENCV_COMPONENTS "opencv_java" CACHE STRING "")
message(STATUS "ANDROID_ABI=${ANDROID_ABI}")
find_package(OpenCV REQUIRED COMPONENTS ${ANDROID_OPENCV_COMPONENTS})
以下是详细的程序:

set(ANDROID_OPENCV_COMPONENTS "opencv_java" CACHE STRING "")
message(STATUS "ANDROID_ABI=${ANDROID_ABI}")
find_package(OpenCV REQUIRED COMPONENTS ${ANDROID_OPENCV_COMPONENTS})