14

シンプルなopenCV Androidプログラムを実行しようとしています。こちらの手順に従ってAndroid 用の OpenCV をダウンロードしてインストールし、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)

注意すべき2つのこと:私はこのコードでネイティブなものを直接使用していません(ここでの他の質問のように)、古い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

解決策は、OpenCV Manager の使用に関する @Jason の回答のようにすることです。こちらの公式ドキュメントでも詳しく説明されています。

しかし、@Jasonが言うように、「アプリが機能する前に、ユーザーがいくつかのパッケージを手動でインストールする必要があるようにします」。これは事実ですが、OpenCV Managerには次のような利点があります。

  • OpenCV が更新された場合、ユーザーはマネージャー/ライブラリを更新するだけで済みます。マネージャーを使用するアプリケーションは同じままでかまいません。

  • アプリ apk のサイズはかなり小さくなります。

    • 単純な opencv アプリは、アプリごとに約 400KB + OpenCV マネージャー用に約 800KB +デバイス アーキテクチャ用にコンパイルされた OpenCV ライブラリ用に約 12MB になります。
    • 従来の静的リンクでは、デバイス内のすべてのopencv アプリは少なくとも 25 MB 程度になります。
    • もちろん、これらのサイズは、アプリ内に配置するものの量によって異なります...

それでも、従来の方法である静的リンクでアプリをデプロイする場合は、こちらの手順を参照してください

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

You can statically load the open cv library everywhere in your activity. Search the .so file in your jniLibs folder and copy/paste it as argument of "loadLibrary" method without the lib prefix.

于 2015-06-27T15:18:16.903 に答える