14

只是想做一个简单的openCV android程序。按照此处的说明下载并安装 OpenCV for Android ,并将 OpenCV 库 2.4.2 添加为我自己的 android 项目的库项目,如说明状态。

但是,当我编译标准的“Hello World Program”时,如下所示,如果我包含该Mat mat = new Mat();行,它会失败,否则会成功。

package com.example;

import org.opencv.core.Mat;

import android.app.Activity;
import android.os.Bundle;

public class HelloAndroidActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Mat mat = new Mat();
    }
}

这是它打印出来的堆栈跟踪:

    07-23 09:59:43.835: E/AndroidRuntime(8222): FATAL EXCEPTION: main
07-23 09:59:43.835: E/AndroidRuntime(8222): java.lang.UnsatisfiedLinkError: n_Mat
07-23 09:59:43.835: E/AndroidRuntime(8222):     at org.opencv.core.Mat.n_Mat(Native Method)
07-23 09:59:43.835: E/AndroidRuntime(8222):     at org.opencv.core.Mat.<init>(Mat.java:181)
07-23 09:59:43.835: E/AndroidRuntime(8222):     at com.example.HelloAndroidActivity.onCreate(HelloAndroidActivity.java:15)
07-23 09:59:43.835: E/AndroidRuntime(8222):     at android.app.Activity.performCreate(Activity.java:4538)
07-23 09:59:43.835: E/AndroidRuntime(8222):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1071)
07-23 09:59:43.835: E/AndroidRuntime(8222):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2161)
07-23 09:59:43.835: E/AndroidRuntime(8222):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2240)
07-23 09:59:43.835: E/AndroidRuntime(8222):     at android.app.ActivityThread.access$600(ActivityThread.java:139)
07-23 09:59:43.835: E/AndroidRuntime(8222):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1262)
07-23 09:59:43.835: E/AndroidRuntime(8222):     at android.os.Handler.dispatchMessage(Handler.java:99)
07-23 09:59:43.835: E/AndroidRuntime(8222):     at android.os.Looper.loop(Looper.java:154)
07-23 09:59:43.835: E/AndroidRuntime(8222):     at android.app.ActivityThread.main(ActivityThread.java:4977)
07-23 09:59:43.835: E/AndroidRuntime(8222):     at java.lang.reflect.Method.invokeNative(Native Method)
07-23 09:59:43.835: E/AndroidRuntime(8222):     at java.lang.reflect.Method.invoke(Method.java:511)
07-23 09:59:43.835: E/AndroidRuntime(8222):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
07-23 09:59:43.835: E/AndroidRuntime(8222):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
07-23 09:59:43.835: E/AndroidRuntime(8222):     at dalvik.system.NativeStart.main(Native Method)

需要注意的两件事:我没有直接在这段代码中使用任何本机内容(就像这里的其他一些问题一样),旧的 OpenCV 2.3.x 库在使用相同的方法之前工作得很好。两个 Android 项目具有相同的目标和受支持的 API 设置。

4

3 回答 3

19

弄清楚了。没有静态链接库。如果您改用此代码,它可以工作。

package com.example;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class HelloAndroidActivity extends Activity
{

    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");
      // Create and set View
      setContentView(R.layout.main);
       } break;
       default:
       {
      super.onManagerConnected(status);
       } break;
   }
    }
};

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
    Log.i(TAG, "onCreate");
    super.onCreate(savedInstanceState);

    Log.i(TAG, "Trying to load OpenCV library");
    if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mOpenCVCallBack))
    {
      Log.e(TAG, "Cannot connect to OpenCV Manager");
    }
}
}

不过,不太喜欢这种“OpenCV Manager”的想法。使得用户必须在应用程序运行之前手动安装几个包。

于 2012-07-23T14:26:10.077 回答
3

解决方案是要么像@Jason 回答中那样使用 OpenCV 管理器。这里的官方文档也有详细的解释。

但就像@Jason 所说,“这样做是为了让用户必须在应用程序运行之前手动安装多个包”。虽然这是真的,但OpenCV Manager有一些优点,例如:

  • 如果 OpenCV 更新,用户只需要更新管理器/库。使用管理器的应用程序可以保持不变。

  • 您的应用 apk 大小会小很多:

    • 一个简单的 opencv 应用程序大约为每个应用程序约 400KB + OpenCV Manager 约 800KB +为您的设备架构编译的 OpenCV 库约 12MB。
    • 使用传统的静态链接,您设备中的每个opencv 应用程序将至少约为 25MB。
    • 当然,这些大小取决于您在应用程序中放置的东西的数量......

即便如此,如果您希望以传统方式(静态链接)部署您的应用程序,您可以阅读此处的说明

于 2012-09-30T14:28:40.893 回答
2
 static{System.loadLibrary("opencv_java3"); } //the name of the .so file, without the 'lib' prefix

您可以在活动的任何地方静态加载打开的 cv 库。在 jniLibs 文件夹中搜索 .so 文件并将其复制/粘贴为“loadLibrary”方法的参数,不带 lib 前缀。

于 2015-06-27T15:18:16.903 回答