17

几天前,我询问了一个UnsatisfiedLinkError运行非本地 OpenCV 代码的问题。onCreate()我以为在重新安装 Eclipse 并关闭/重新打开所有包后问题就解决了,但是在我将 OpenCV 代码放入现有方法 后又回来了。

我用一个名为 Start 的活动创建了一个新的 Android 应用程序。然后我转到项目属性并将 OpenCV 添加为库。这是活动的代码(Start.java):

package com.test;

import org.opencv.core.Mat;
import org.opencv.highgui.Highgui;

import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.view.Menu;

public class Start extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_start);

        Mat Image = Highgui.imread("/image.jpg");
        if (Image == null) {
            AlertDialog ad = new AlertDialog.Builder(this).create(); 
            ad.setMessage("Fatal error: can't open /image.jpg!");  
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_start, menu);
        return true;
    }
}

这是日志:

08-13 12:26:14.791: E/Trace(1067): error opening trace file: No such file or directory (2)
08-13 12:26:15.191: W/dalvikvm(1067): No implementation found for native Lorg/opencv/highgui/Highgui;.imread_1:(Ljava/lang/String;)J
08-13 12:26:15.191: D/AndroidRuntime(1067): Shutting down VM
08-13 12:26:15.191: W/dalvikvm(1067): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
08-13 12:26:15.201: E/AndroidRuntime(1067): FATAL EXCEPTION: main
08-13 12:26:15.201: E/AndroidRuntime(1067): java.lang.UnsatisfiedLinkError: Native method not found: org.opencv.highgui.Highgui.imread_1:(Ljava/lang/String;)J
08-13 12:26:15.201: E/AndroidRuntime(1067):     at org.opencv.highgui.Highgui.imread_1(Native Method)
08-13 12:26:15.201: E/AndroidRuntime(1067):     at org.opencv.highgui.Highgui.imread(Highgui.java:324)
08-13 12:26:15.201: E/AndroidRuntime(1067):     at com.test.Start.onCreate(Start.java:18)
08-13 12:26:15.201: E/AndroidRuntime(1067):     at android.app.Activity.performCreate(Activity.java:5008)
08-13 12:26:15.201: E/AndroidRuntime(1067):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
08-13 12:26:15.201: E/AndroidRuntime(1067):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
08-13 12:26:15.201: E/AndroidRuntime(1067):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
08-13 12:26:15.201: E/AndroidRuntime(1067):     at android.app.ActivityThread.access$600(ActivityThread.java:130)
08-13 12:26:15.201: E/AndroidRuntime(1067):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
08-13 12:26:15.201: E/AndroidRuntime(1067):     at android.os.Handler.dispatchMessage(Handler.java:99)
08-13 12:26:15.201: E/AndroidRuntime(1067):     at android.os.Looper.loop(Looper.java:137)
08-13 12:26:15.201: E/AndroidRuntime(1067):     at android.app.ActivityThread.main(ActivityThread.java:4745)
08-13 12:26:15.201: E/AndroidRuntime(1067):     at java.lang.reflect.Method.invokeNative(Native Method)
08-13 12:26:15.201: E/AndroidRuntime(1067):     at java.lang.reflect.Method.invoke(Method.java:511)
08-13 12:26:15.201: E/AndroidRuntime(1067):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
08-13 12:26:15.201: E/AndroidRuntime(1067):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
08-13 12:26:15.201: E/AndroidRuntime(1067):     at dalvik.system.NativeStart.main(Native Method)

同样,这是非本地代码,因此出现 Unsatisfied Link Error 没有多大意义。

4

8 回答 8

38

经过一堆搜索,我发现了这个

“3.如果你的应用项目没有JNI部分,只需将对应的OpenCV原生库从/sdk/native/libs/复制到你的项目目录到文件夹libs/中即可。”

这意味着复制 \armeabi、\armeabi-v7a 和 \x86 文件夹。

"4. 在您​​的应用程序中启用 OpenCV 的最后一步是调用 OpenCV API 之前的 Java 初始化代码。例如,可以在 Activity 类的静态部分中完成,该部分仅在任何实例之前执行一次创建类:

static {
    if (!OpenCVLoader.initDebug()) {
        // Handle initialization error
    }
}

或者,您可以将其放在 onCreate 方法中:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_load_image);
    if (!OpenCVLoader.initDebug()) {
        // Handle initialization error
    }
    [...]
}

现在它起作用了!

于 2012-08-14T01:32:16.963 回答
8

你应该使用

if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack))
{
    Log.e("TEST", "Cannot connect to OpenCV Manager");
}

在 OnCreate() 并使用

private BaseLoaderCallback  mOpenCVCallBack = new BaseLoaderCallback(this) {
    @Override
    public void onManagerConnected(int status) {
        switch (status) {
                case LoaderCallbackInterface.SUCCESS:
                {
                               Mat Image = Highgui.imread("/image.jpg");
                               if (Image == null) {
                                   AlertDialog ad = new AlertDialog.Builder(this).create(); 
                                   ad.setMessage("Fatal error: can't open /image.jpg!");  
                                }
                } break;
                default:
                {
                    super.onManagerConnected(status);
                } break;
            }
    }
    };
于 2012-10-05T09:02:48.010 回答
7

在大多数情况下,在调用 openCV 之前这样一行就足够了:“System.loadLibrary(Core.NATIVE_LIBRARY_NAME);”

于 2013-12-03T18:23:10.550 回答
3

我在 Android Studio 的项目中添加了 opencv。当本机文件在运行时不可用时,会发生此错误。因此,您必须将本机文件复制到正确的位置。

首先jniLibs在此位置/app/src/main/位置创建并复制 OpenCV SDK 的 jniLibs 中带有 *.so 文件(armeabi、armeabi-v7a、mips、x86)的所有文件夹,并使您的 gradle 插件高于 0.7.2+

在此处输入图像描述

于 2014-03-16T16:22:05.313 回答
2

问题是您在OpenCV4Android库完成加载之前就使用了Highgui.imread方法。Android 在加载OpenCV4Android库之前调用“onCreate”方法。因此,为您的 OpenCV 代码创建一个单独的方法,如下所示:-

public class Start extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_start);
   }

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_start, menu);
    return true;
   }

public void readImage {
    Mat Image = Highgui.imread("/image.jpg");
    if(Image=null) {
    Log.i("Start", "--------Image Cannot be Loaded--------");
    else if(!Image=null) {
    Log.i("Start", "--------Image Loaded Successfully--------");
   }

}

于 2013-08-27T17:10:53.447 回答
1

答案中的链接不起作用,我不得不四处寻找适合我的解决方案。

我首先在类中定义了一个 BaseLoaderCallback

private BaseLoaderCallback  mLoaderCallback = new BaseLoaderCallback(this) {
    @Override
    public void onManagerConnected(int status) {
        switch (status) {
            case LoaderCallbackInterface.SUCCESS:
            {
                Log.i(TAG, "OpenCV loaded successfully");
               // any immediate code for using OpenCV
            } break;
            default:
            {
                super.onManagerConnected(status);
            } break;
        }
    }
};

然后在 onResume 函数中我有:

@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_0_0, this, mLoaderCallback);
    } else {
        Log.d(TAG, "OpenCV library found inside package. Using it!");
        mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);

    }
}

确保以下内容

1.您正在根据您的版本更改 OPENCV_VERSION_3_0_0

  1. 在加载之前不要运行任何 opencv 库。即使在onCreate(),opencv 还没有加载。最好将它放在OpenCV 已成功加载onManagerConnected()的 switch case 中的函数中。
于 2016-04-24T15:20:56.950 回答
0

在我的情况下,我将 opencv 类粘贴到错误的包名中

错了一个

我将 opencv 类粘贴到com.opencv -> all classes

正确一个

org.opencv -> 所有类

更改此正确的包名称后,它将起作用。

原因 - 他们可能指的是“org.opencv..”

于 2019-03-31T11:57:38.073 回答
0

我已经为此花费了几个小时,但找不到有效的解决方案。这对我有用,请查看我对类似问题的回答。

https://stackoverflow.com/a/65832050/6212983

于 2021-01-21T17:48:09.467 回答