2012-07-23 3 views
14

juste en essayant de faire un simple programme android openCV. Téléchargé et installé OpenCV pour Android en suivant le instructions here et ajouté OpenCV Library 2.4.2 en tant que projet de bibliothèque pour mon propre projet android comme l'état des instructions.Android UnsatisfiedLinkError avec OpenCV 2.4.2

Cependant, lorsque je compile le "programme Hello World" standard, comme suit, échoue si j'inclue la ligne Mat mat = new Mat();, mais réussit autrement.

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

est ici la trace de la pile, il imprime:

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) 

Deux choses à noter: Je ne suis pas directement avec quoi que ce soit natif dans ce code (comme d'autres questions sur ici) et l'ancien OpenCV 2.3 La bibliothèque .x a bien fonctionné avant d'utiliser la même méthode. Les deux projets Android ont la même cible et les mêmes paramètres d'API.

+0

où vous avez placé cette bibliothèque "org.opencv.core.Mat". assurez-vous que ce fichier jar est dans le dossier libs. –

+1

Ajout de ce code résolu mon problème. 'static {System.loadLibrary (" opencv_java3 "); } ' –

Répondre

19

Compris. N'a pas lié statiquement la bibliothèque. Si vous utilisez ce code à la place, cela fonctionne.

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

Cependant, pas trop friands de cette idée "OpenCV Manager". Le fait que l'utilisateur doit installer plusieurs paquets manuellement avant que l'application ne fonctionne.

+0

Mon problème est également le même .. et toujours aux prises avec la même erreur.pouvez-vous s'il vous plaît m'aider avec plus de solutions ??? – Rekha

+1

Avez-vous essayé d'utiliser mon code? – Jason

+1

Non je n'ai pas essayé votre code..mais maintenant mon problème est résolu..mon erreur était vraiment vil idiot ... c'est-à-dire que j'ai défini Mat m = new Mat(), avant d'appeler la librairie..aussi donné l'erreur..mais c'était imperceptible pendant 2 jours .. – Rekha

3

La solution est de faire comme dans @Jason réponse qui est sur l'utilisation de l'OpenCV Manager. Il est également expliqué en détail sur le official documentation here. Mais, comme le dit @Jason, «il faut que l'utilisateur installe manuellement plusieurs paquets avant que l'application ne fonctionne». Bien que ce soit vrai, OpenCV directeur présente certains avantages comme par exemple:

  • Si OpenCV est mis à jour, l'utilisateur n'a besoin que de mettre à jour le gestionnaire/bibliothèque. Les applications qui utilisent le gestionnaire peuvent rester les mêmes.

  • Votre application taille apk sera beaucoup plus petit:

    • Une simple application de OpenCV sera d'environ ~ 400 Ko pour chaque application + ~ 800KB pour OpenCV Directeur + ~ 12 Mo pour la bibliothèque OpenCV compilé pour l'architecture de votre appareil.
    • Avec la liaison statique traditionnelle chaque application opencv dans votre appareil serait au moins ~ 25 Mo.
    • Ces tailles dépendent, bien sûr, la quantité de choses que vous placez dans votre application ...

Même si, si vous souhaitez déployer vos applications de façon traditionnelle, statique reliantyou can read the instructions here.

+5

"Si OpenCV est mis à jour, l'utilisateur n'a besoin que de mettre à jour le gestionnaire/la bibliothèque." C'est probablement une mauvaise chose. Vous souhaitez garder le contrôle de la version que vous utilisez sinon il n'y a pas de période de latence pour tester si votre application fonctionne avec la dernière version. QA de base ... – pablisco

+0

Certes, je n'ai pas suivi les développements récents, mais il devrait y avoir un mécanisme permettant aux applications de contrôler la gamme de versions avec lesquelles elles sont compatibles. Si ce n'est pas le cas, c'est un problème. –

+1

Une autre alternative est d'avoir plusieurs APK cible pour chacune des 4 architectures de CPU ciblées (ou une seule, x86 et mips ne sont pas étendues). Cela donne seulement un surcoût de 4 Mo, ce qui devrait être correct. – pablisco

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

Vous pouvez charger statiquement la bibliothèque cv ouverte partout dans votre activité. Recherchez le fichier .so dans votre dossier jniLibs et copiez/collez-le comme argument de la méthode "loadLibrary" sans le préfixe lib.

Questions connexes