2012-07-23 10 views
14

solo cercando di fare un semplice programma Android openCV. Scaricato e installato OpenCV per Android dopo il instructions here e aggiunto OpenCV Library 2.4.2 come progetto di libreria per il mio progetto Android come lo stato delle istruzioni.Android UnsatisfiedLinkError con OpenCV 2.4.2

Tuttavia, quando compilo lo "Hello World Program" standard, come segue, fallisce se includo la riga Mat mat = new Mat();, ma succede diversamente.

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

Ecco la traccia dello stack esso stampa:

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) 

Due cose da notare: io non sono direttamente utilizzando nulla nativo in questo codice (come alcune altre domande su qui) e il vecchio OpenCV 2.3 La libreria .x ha funzionato bene prima di usare lo stesso metodo. Entrambi i progetti Android hanno lo stesso target e le impostazioni API supportate.

+0

dove è stata inserita questa libreria "org.opencv.core.Mat". assicurati che questo file jar sia nella cartella libs. –

+1

L'aggiunta di questo codice ha risolto il mio problema. 'static {System.loadLibrary (" opencv_java3 "); } ' –

risposta

19

Capito. Non stava collegando staticamente la libreria. Se si utilizza questo codice, invece, funziona.

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

Tuttavia, non troppo appassionato di questa idea di "OpenCV Manager". Fa in modo che l'utente debba installare diversi pacchetti manualmente prima che l'app funzioni.

+0

Il mio problema è lo stesso ... e sto ancora lottando con lo stesso errore ... puoi aiutarmi con più soluzioni ??? – Rekha

+1

Hai provato a usare il mio codice? – Jason

+1

No, non ho provato il tuo codice ... ma ora il mio problema è risolto ... il mio errore è stato davvero vry stupido ... cioè ho definito Mat m = new Mat(), prima di chiamare la libreria ... così ha dato l'errore..ma era impercettibile per 2 giorni .. – Rekha

3

La soluzione è fare come in @Jason answer che riguarda l'uso di OpenCV Manager. Viene anche spiegato dettagliatamente sul numero official documentation here.

Ma come dice @Jason, "rende così l'utente deve installare pacchetti manualmente manualmente prima che l'app funzioni". Anche se questo è vero, OpenCV Responsabile ha alcuni vantaggi, come ad esempio:

  • Se OpenCV viene aggiornato, l'utente deve solo aggiornare il manager/biblioteca. Le applicazioni che utilizzano il gestore possono rimanere invariate.

  • La dimensione app APK sarà molto più piccolo:

    • Una semplice OpenCV applicazione sarà di circa ~ 400KB per ogni app + ~ 800KB per OpenCV Direttore + ~ 12 MB per la libreria OpenCV compilato per l'architettura del dispositivo.
    • Con il collegamento statico tradizionale ogni singola app opencv sul dispositivo è di almeno ~ 25 MB.
    • Queste dimensioni dipendono, fuori rotta, sulla quantità di roba che si inserisce all'interno della vostra app ...

Anche così, se si desidera distribuire le applicazioni in modo tradizionale, statica che collega , you can read the instructions here.

+5

"Se OpenCV è aggiornato, l'utente deve solo aggiornare il gestore/libreria." Probabilmente è una brutta cosa. Si desidera mantenere il controllo della versione in uso altrimenti non è previsto un periodo di latenza per verificare se l'app funziona con la versione più recente. QA di base ... – pablisco

+0

Vero, non ho seguito gli sviluppi recenti, ma dovrebbe esserci un meccanismo per le app per controllare la gamma di versioni con cui sono compatibili. Se non c'è, è un problema. –

+1

Un'altra alternativa è avere più APK di destinazione per ognuna delle 4 architetture di cpu mirate (o solo una, x86 e mips non sono così estese). Questo dà solo un overhead 4mb, che dovrebbe essere ok. – pablisco

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

È possibile caricare staticamente la libreria cv aperta ovunque nella propria attività. Cercare il file .so nella cartella jniLibs e copiarlo/incollarlo come argomento del metodo "loadLibrary" senza il prefisso lib.