Android UnsatisfiedLinkError с OpenCV 2.4.2 - программирование
Подтвердить что ты не робот

Android UnsatisfiedLinkError с OpenCV 2.4.2

просто пытается сделать простую программу openCV android. Загрузили и установили OpenCV для Android в соответствии с инструкциями здесь и добавили OpenCV Library 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.

4b9b3361

Ответ 1

Выяснил это. Не статически связывала библиотеку. Если вы используете этот код, он работает.

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. Делает это так, что пользователь должен установить несколько пакетов вручную, прежде чем приложение будет работать.

Ответ 2

Решение состоит в том, чтобы либо сделать, как в ответе @Jason, который посвящен использованию OpenCV Manager. Здесь также подробно объясняется официальная документация .

Но, как @Jason говорит: "Делает так, чтобы пользователю пришлось устанавливать отдельные пакеты вручную до того, как приложение будет работать". Хотя это верно, OpenCV Manager имеет ряд преимуществ, например:

  • Если OpenCV обновлен, пользователю необходимо обновить менеджер/библиотеку. Приложения, которые используют диспетчер, могут оставаться неизменными.

  • Размер вашего приложения apk будет намного меньше:

    • Простое приложение opencv будет около ~ 400 КБ для каждого приложения + ~ 800 КБ для OpenCV Manager + ~ 12 МБ для библиотеки OpenCV, скомпилированной для вашей архитектуры устройства.
    • При традиционном статическом привязке каждое приложение opencv на вашем устройстве будет не менее ~ 25 МБ.
    • Эти размеры зависят, конечно, от количества вещей, которые вы размещаете внутри своего приложения...

Тем не менее, если вы хотите развернуть свои приложения традиционным способом, статические ссылки, вы можете прочитать инструкции здесь.

Ответ 3

 static{System.loadLibrary("opencv_java3"); } //the name of the .so file, without the 'lib' prefix

Вы можете статически загружать открытую библиотеку cv всюду в своей деятельности. Найдите файл .so в папке jniLibs и скопируйте/вставьте его в качестве аргумента метода loadLibrary без префикса lib.