android - 未找到 native 方法 : org. opencv.core.Mat.n_Mat:()J

标签 android opencv android-studio

我正在使用原生 android Opencv 3.1.0 库 但总是显示这样的错误

java.lang.UnsatisfiedLinkError: Native method not found: org.opencv.core.Mat.n_Mat:()J

这是我的代码

package com.example.saya.cameraopencv;

public class Hasil extends AppCompatActivity{

private TextView coba;
private ImageView gambarskrg;
private Mat rgba;

final String TAG = "Hello World";

private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {
    @Override
    public void onManagerConnected(int status) {
        switch (status) {
            case LoaderCallbackInterface.SUCCESS:
            {
                Log.i(TAG, "OpenCV loaded successfully");           
            } break;
            default:
            {
                super.onManagerConnected(status);
            } break;
        }
    }
};
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.hasil_activity);
    OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_1_0, this, mOpenCVCallBack);
    Bundle i = getIntent().getExtras();

    gambarskrg = (ImageView) findViewById(R.id.gambar);

    String gambar = Environment.getExternalStorageDirectory()+ "/Coba/Coba_1476987074709.jpg";

    Bitmap bmp = BitmapFactory.decodeFile(gambar);

    Log.i(TAG, "Trying to load OpenCV library");
    if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_1_0, this, mOpenCVCallBack))
    {
        Log.e(TAG, "Cannot connect to OpenCV Manager");
    }
    else {
        Log.e(TAG, "Berhasil");
        try {
            detectEdges(bmp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

private void detectEdges(Bitmap bmp){
    Mat rgba = new Mat();
    Utils.bitmapToMat(bmp, rgba);

    Mat edges = new Mat(rgba.size(), CvType.CV_8UC4);
    Imgproc.cvtColor(rgba, edges, Imgproc.COLOR_RGBA2GRAY, 4);
    Imgproc.Canny(edges, edges, 80, 100);

    Bitmap resultBitmap = Bitmap.createBitmap(edges.cols(), edges.rows(), Bitmap.Config.ARGB_8888);
    Utils.matToBitmap(edges, resultBitmap);
    int nh = (int) ( resultBitmap.getHeight() * (512.0 / resultBitmap.getWidth()) );
    Bitmap scaled = Bitmap.createScaledBitmap(resultBitmap, 512, nh, true);
    gambarskrg.setImageBitmap(scaled);
}

}

这是 logcat

10-21 04:02:32.333 21528-21528/com.example.saya.cameraopencv E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.saya.cameraopencv, PID: 21528 java.lang.UnsatisfiedLinkError: Native method not found: org.opencv.core.Mat.n_Mat:()J at org.opencv.core.Mat.n_Mat(Native Method) at org.opencv.core.Mat.(Mat.java:24) at com.example.saya.cameraopencv.Hasil.detectEdges(Hasil.java:88) at com.example.saya.cameraopencv.Hasil.onCreate(Hasil.java:79) at android.app.Activity.performCreate(Activity.java) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java) at android.app.ActivityThread.access$800(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java) at android.os.Handler.dispatchMessage(Handler.java) at android.os.Looper.loop(Looper.java) at android.app.ActivityThread.main(ActivityThread.java) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java) at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132) at dalvik.system.NativeStart.main(Native Method)

最佳答案

代码存在一些问题。在你的onCreate方法,您调用OpenCVLoader.initAsync方法两次,第一次在setContentView之后,第二次出现在 Log.i(TAG, "Trying to load OpenCV library") 之后的 if 语句中信息。您应该只调用OpenCVLoader.initAsync方法一次,OpenCV4Android SDK 附带的许多示例都执行此操作 onResume方法。要更好地了解原因,请查看 this article它描述了 Activity 生命周期。

这里的第二个问题是您正在尝试创建 Mat OpenCV 完成初始化之前的对象。在创建 Mat 之前,您必须首先等待调用 OpenCV 初始化方法的异步任务返回到 UIThread。目的。当 OpenCV 初始化线程运行完毕后,它会调用 onManagerConnected方法。因此,要解决您的问题,您必须在 onManagerConnected 中调用 Mat 初始化代码。方法以确保仅在 OpenCV 初始化代码执行完成后调用它。下面是它的外观示例:

private Bitmap bmp;
final String TAG = "Hello World";    

private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
    @Override
    public void onManagerConnected(int status) {
        switch (status) {
            case LoaderCallbackInterface.SUCCESS: {
                Log.i(TAG, "OpenCV loaded successfully");
                try {
                    detectEdges(bmp);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            break;
            default: {
                super.onManagerConnected(status);
            }
            break;
        }
    }
};

@Override
public void onResume() {
    super.onResume();
    if (!OpenCVLoader.initDebug()) {
        Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_1_0, this, mLoaderCallback);
    } else {
        Log.d(TAG, "OpenCV library found inside package. Using it!");
        mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.hasil_activity);
    Bundle i = getIntent().getExtras();
    String gambar = Environment.getExternalStorageDirectory()+ "/Coba/Coba_1476987074709.jpg";
    bmp = BitmapFactory.decodeFile(gambar);
}

private void detectEdges(Bitmap bmp){
    Mat rgba = new Mat();
    Utils.bitmapToMat(bmp, rgba);

    Mat edges = new Mat(rgba.size(), CvType.CV_8UC4);
    Imgproc.cvtColor(rgba, edges, Imgproc.COLOR_RGBA2GRAY, 4);
    Imgproc.Canny(edges, edges, 80, 100);

    Bitmap resultBitmap = Bitmap.createBitmap(edges.cols(), edges.rows(), Bitmap.Config.ARGB_8888);
    Utils.matToBitmap(edges, resultBitmap);
    int nh = (int) ( resultBitmap.getHeight() * (512.0 / resultBitmap.getWidth()) );
    Bitmap scaled = Bitmap.createScaledBitmap(resultBitmap, 512, nh, true);
    ((ImageView) findViewById(R.id.gambar)).setImageBitmap(scaled);
}

此外,由于您从外部存储器读取图像,因此您可能需要请求用户许可才能从存储器中读取图像,具体取决于您所定位的 Android 版本。您可以通过将以下代码添加到您的 Android list 中来完成此操作:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

关于android - 未找到 native 方法 : org. opencv.core.Mat.n_Mat:()J,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40163787/

相关文章:

android - 有人可以了解我的 Google Play Android 应用程序的确切名称和概念吗?

android - 如何通过sql查询进行日期比较?

android - 如何在后台为 ScrollView 委托(delegate)触摸事件?

python - 我如何导入cv2

c++ - OpenCV C++ Mat 类行和列 - 它们是成员变量(和相关问题)吗?

java - Android Studio 应用程序甚至在使用 Libgdx 打开之前就停止工作

android - AVD 未启动(无错误消息)

android - 无法在 Android Studio 中运行模拟器

Android - 微调器默认边距

c++ - OpenCV2.4错误: No GPU support in unknown function file