数日前、私は 質問 非ネイティブOpenCVコードの実行によるUnsatisfiedLinkError
について。 Eclipseを再インストールし、すべてのパッケージを閉じて再度開くと問題は解決すると思ったのですが、OpenCVコードを既存のonCreate()
メソッドに挿入した後で再び問題が発生しました。
Start AndroidアプリケーションをStartというアクティビティで作成しました。次に、プロジェクトのプロパティに移動し、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が発生してもあまり意味がありません。
たくさん検索した後、私は this を見つけました:
「3.アプリケーションプロジェクトにJNIパーツがない場合は、対応するOpenCVネイティブライブラリを/ sdk/native/libs /からプロジェクトディレクトリのlibs /フォルダーにコピーするだけです。」
つまり、\ armeabi、\ armeabi-v7a、および\ x86フォルダーをコピーします。
"4.アプリケーションでOpenCVを有効にする最後の手順は、OpenCV APIを呼び出す前のJava初期化コードです。これは、たとえば、Activityクラスの静的セクションで実行できます。クラスのインスタンスが作成される前に、1回だけ実行されます。
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
}
[...]
}
今ではうまくいきます!
あなたは使うべきです
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;
}
}
};
ほとんどの場合、openCVを呼び出す前に次のような行で十分です: "System.loadLibrary(Core.NATIVE_LIBRARY_NAME);"
Android Studioのプロジェクトにopencvを追加していました。このエラーは、実行時にネイティブファイルが利用できない場合に発生します。したがって、ネイティブファイルを正しい場所にコピーする必要があります。
まず、この場所にjniLibs
を作成します/app/src/main/
場所と* .soファイル(armeabi、armeabi-v7a、mips、x86)を含むすべてのフォルダーをOpenCV SDKのjniLibsにコピーし、gradleプラグインを0.7.2+以上にします
問題はHighgui.imreadメソッドをOpenCV4Androidライブラリもロードを完了します。 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--------");
}
}
答えのリンクは機能していなかったので、うまくいく解決策を見つけるためにしばらくの間調査する必要がありました。
最初にクラスで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を変更します
onCreate()
でも、opencvはまだロードされていません。 OpenCVが正常にロードされたスイッチケースのonManagerConnected()
関数に配置することをお勧めします。私の場合、opencvクラスを間違ったパッケージ名で貼り付けました
Opencvクラスをcom.opencv->すべてのクラスに貼り付けます
org.opencv->すべてのクラス
この正しいパッケージ名を変更すると機能します。
理由-「org.opencv ..」を参照している可能性があります。