Android UnsatisfiedLinkError with OpenCV 2.4.2
Asked Answered
A

3

14

just trying to do a simple openCV android program. Downloaded and installed OpenCV for Android following the instructions here and added the OpenCV Library 2.4.2 as a library project for my own android project like the instructions state.

However when I compile the standard "Hello World Program", as follows, it fails if I include the Mat mat = new Mat(); line, but succeeds otherwise.

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

Here's the stack trace it prints out:

    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)

Two things to note: I am not directly using anything native in this code (like some other questions on here) and the old OpenCV 2.3.x library worked just fine before using the same method. Both Android projects have the same target and supported API settings.

Almswoman answered 23/7, 2012 at 14:9 Comment(2)
where you have placed this lib "org.opencv.core.Mat". make sure this jar file is in libs folder.Ingratiate
Adding this code resolved my problem. static{ System.loadLibrary("opencv_java3"); }Sievert
A
19

Figured it out. Wasn't statically linking the library. If you use this code instead, it works.

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

However, not too fond of this "OpenCV Manager" idea. Makes it so the user has to install several packages manually before the app will work.

Almswoman answered 23/7, 2012 at 14:26 Comment(5)
My Problem is also the same..and still struggling with the same error..can you please help me with more solutions???Nodular
Nope I haven't tried your code..but now my problem is solved..my mistake was really vry silly...that is i have defined Mat m = new Mat(), before calling the library..so it gave the error..but it was unnoticeable for 2 days..Nodular
Haha nice. Glad you solved it. I'm sure I've had similar issues.Almswoman
Thank you @Nodular for telling your "silly" mistake! I was using OpenCV classes between different classes and I made the same mistake. Your comment solved it! :)Trinitarianism
does javaCV way of code.google.com/p/javacv/#Quick_Start_for_OpenCV_and_FFmpeg won;t work for openCV ,Tusk
R
3

The solution is to either do like in @Jason answer which is about using the OpenCV Manager. It is also explained in great detail on the official documentation here.

But like @Jason says, "Makes it so the user has to install severally packages manually before the app will work". Although this is true, OpenCV Manager has some advantages like for example:

  • If OpenCV is updated, the user only needs to update the manager/library. The applications which use the manager can remain the same.

  • Your app apk size will be a lot smaller:

    • A simple opencv app will be about ~400KB for each app + ~800KB for OpenCV Manager + ~12MB for the OpenCV library compiled for your device architecture.
    • With the traditional static linking every single opencv app in your device would be at least ~25MB.
    • These sizes depend, off course, on the amount of stuff you place inside your app ...

Even so, if you wish to deploy your apps the traditional way, static linking, you can read the instructions here.

Ricker answered 30/9, 2012 at 14:28 Comment(5)
"If OpenCV is updated, the user only needs to update the manager/library." That's probably a bad thing. You want to keep control of the version you are using otherwise there is no latency period to test if your app works with the latest version. Basic QA...Adenoma
True, I have not been following the recent developments but there should be a mechanism for apps to control which range of versions they are compatible with. If there isn't, it is an issue.Ricker
Another alternative is to have multiple target APK for each of the 4 targeted cpu arquitectures (or only one, x86 and mips aren't that extended). This only gives a 4mb overhead, which should be ok.Adenoma
From what I have seen recently there are static constants which lets you assert which version the manager is running.Ricker
The link to static linking really helps! thank u (+1)Colonialism
C
2
 static{System.loadLibrary("opencv_java3"); } //the name of the .so file, without the 'lib' prefix

You can statically load the open cv library everywhere in your activity. Search the .so file in your jniLibs folder and copy/paste it as argument of "loadLibrary" method without the lib prefix.

Chirm answered 27/6, 2015 at 15:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.