2012-07-23 13 views
14

po prostu próbuje zrobić prosty program Android OpenCV. Pobrałem i zainstalowałem OpenCV dla Androida po instructions here i dodałem OpenCV Library 2.4.2 jako projekt biblioteki dla mojego własnego projektu Android, takiego jak stan instrukcji.Android UnsatisfiedLinkError z OpenCV 2.4.2

Jednak, gdy skompiluję standardowy "Program Hello World", jak następuje, nie powiedzie się, jeśli dołączę linię Mat mat = new Mat();, ale uda się inaczej.

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(); 
    } 
} 

Oto ślad stosu wypisze:

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) 

Dwie rzeczy do uwaga: nie jestem bezpośrednio za pomocą niczego natywną w tym kodzie (jak niektóre inne pytania tutaj) i stary OpenCV 2.3 .x biblioteka działała dobrze przed użyciem tej samej metody. Oba projekty Androida mają ten sam cel i obsługiwane ustawienia interfejsu API.

+0

gdzie umieściłeś tę bibliotekę "org.opencv.core.Mat". upewnij się, że ten plik jar znajduje się w folderze libs. –

+1

Dodanie tego kodu rozwiązało mój problem. 'static {System.loadLibrary (" opencv_java3 "); } ' –

Odpowiedz

19

Wyliczyłem to. Nie łączył statycznie biblioteki. Jeśli użyjesz tego kodu, zadziała.

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"); 
    } 
} 
} 

Niezbyt lubiany pomysł "OpenCV Manager". Sprawia, że ​​użytkownik musi ręcznie zainstalować kilka pakietów, zanim aplikacja będzie działać.

+0

Mój problem jest również taki sam ... i wciąż boryka się z tym samym błędem .. możesz mi pomóc z większymi rozwiązaniami ??? – Rekha

+1

Czy próbowałeś używać mojego kodu? – Jason

+1

Nie, nie próbowałem twojego kodu ... ale teraz mój problem został rozwiązany .. mój błąd był naprawdę vry głupi ... to znaczy, że zdefiniowałem Mat m = new Mat(), przed wywołaniem biblioteki..to dało błąd .. ale był niezauważalny przez 2 dni .. – Rekha

3

Rozwiązaniem jest albo polubić odpowiedź @Jason, która dotyczy korzystania z OpenCV Manager. Jest również szczegółowo wyjaśniony na official documentation here.

Ale jak @Jason mówi: "Sprawia, że ​​użytkownik musi ręcznie zainstalować pakiety, zanim aplikacja będzie działać". Chociaż to prawda, OpenCV Menedżer ma pewne zalety, takie jak na przykład:

  • Jeśli OpenCV jest aktualizowana, użytkownik musi jedynie aktualizować kierownik/biblioteka. Aplikacje korzystające z menedżera mogą pozostać niezmienione.

  • Twój rozmiar aplikacja apk będzie dużo mniejszy:

    • Prosta aplikacja OpenCV będzie o ~ 400KB dla każdej aplikacji + ~ 800KB dla OpenCV Menedżer + ~ 12MB dla biblioteki OpenCV skompilowany dla architektury twojego urządzenia.
    • W tradycyjnym łączu statycznym każda aplikacja opencv w urządzeniu będzie wynosić co najmniej ~ 25MB.
    • Te rozmiary zależą od oczywiście od ilości rzeczy, które można umieścić wewnątrz aplikacji ...

Nawet więc, jeśli chcesz, aby wdrożyć aplikacje w tradycyjny sposób, statyczne powiązanie , you can read the instructions here.

+5

"Jeśli OpenCV jest zaktualizowany, użytkownik musi tylko zaktualizować menedżera/biblioteki." To chyba zła rzecz. Chcesz zachować kontrolę nad wersją, której używasz, w przeciwnym razie nie będzie okresu oczekiwania na sprawdzenie, czy aplikacja działa z najnowszą wersją. Podstawowa kontrola jakości ... – pablisco

+0

To prawda, że ​​nie śledziłem ostatnich wydarzeń, ale powinien istnieć mechanizm dla aplikacji, który kontrolowałby zakres wersji, z którymi są kompatybilne. Jeśli nie, to jest problem. –

+1

Inną alternatywą jest posiadanie wielu docelowego pakietu APK dla każdego z 4 ukierunkowanych arcusów cpu (lub tylko jeden, x86 i mips nie są rozszerzone). To daje tylko 4mb narzut, który powinien być w porządku. – pablisco

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

Możesz statycznie załadować bibliotekę otwartych cv wszędzie w swojej działalności. Wyszukaj plik .so w folderze jniLibs i skopiuj/wklej jako argument metody "loadLibrary" bez prefiksu lib.

Powiązane problemy