UnsatisfiedLinkError: n_Mat while using opencv2.4.3 with android 4.0

AnShU picture AnShU · Feb 4, 2013 · Viewed 9.9k times · Source

i am using opencv in android. but when i am adding Mat() in my code my application unexpectedly stops after launch. my error log is as below:

FATAL EXCEPTION: main
java.lang.UnsatisfiedLinkError: n_Mat
at org.opencv.core.Mat.n_Mat(Native Method)
at org.opencv.core.Mat.<init>(Mat.java:441)
at com.example.imagepro.MainActivity.onCreate(MainActivity.java:36)
at android.app.Activity.performCreate(Activity.java:4465)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
at android.app.ActivityThread.access$600(ActivityThread.java:123)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)     
at android.app.ActivityThread.main(ActivityThread.java:4424)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)`

my code is

import java.io.File;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;

import org.opencv.android.Utils;
import org.opencv.imgproc.Imgproc;

import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.ImageView;

public class MainActivity extends Activity {

final String TAG = "Hello World";
Mat imgToProcess;

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.activity_main);
       } break;
       default:
       {
      super.onManagerConnected(status);
       } break;
   }
    }
};

@Override
protected 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_3, this, mOpenCVCallBack))
        {
          Log.e(TAG, "Cannot connect to OpenCV Manager");
        }
        else{ Log.i(TAG, "opencv successfully added"); }

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    String path = Environment.getExternalStorageDirectory()+ "/Koala.jpg"; // get image from sd card

     File imgFile = new File(path);

     View v = null;
          if(imgFile.exists())
 {
          Bitmap myBitmap = BitmapFactory.decodeFile(path);                 
         ImageView myImage = (ImageView) findViewById(R.id.imageView);
         myImage.setImageBitmap(myBitmap);
         Log.i(TAG, "opencv successfull 1");
         Mat imgToProcess = new Mat();
         Mat newmat = new Mat();

         Utils.bitmapToMat(myBitmap, imgToProcess); 
         Imgproc.cvtColor(imgToProcess, newmat, Imgproc.COLOR_RGB2GRAY); 
 Bitmap outImage = Bitmap.createBitmap(newmat.rows(),newmat.cols(),Bitmap.Config.ARGB_8888);
         Utils.matToBitmap(newmat, outImage);

         myImage.setImageBitmap(outImage); 

   }

 }

}

i tried other solutions provided on stackoverflow but none of them worked for me. i have already copied libopencv_java.so and libopencv_info.so into my /libs folder from F:\OpenCV-2.4.3.2-android-sdk\sdk\native\libs\armeabi-v7a but this error remains same.

please help.

thanks in advance :)

Answer

AnShU picture AnShU · May 28, 2013

its good that someone prompted me to post my answer elaborately. so here i am posting the solution of my question :

private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {
     @Override
     public void onManagerConnected(int status) {
       switch (status) {
           case LoaderCallbackInterface.SUCCESS:
           {
              Log.i(TAG, "OpenCV loaded successfully");
              startDisplay();

           } break;


           default:
           {
               super.onManagerConnected(status);
           } break;
         }
      }
 };

    @Override
    protected void onCreate(Bundle savedInstanceState) {


         super.onCreate(savedInstanceState);
         Log.i(TAG, "Trying to load OpenCV library");
         if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mOpenCVCallBack))
         {
           Log.e(TAG, "Cannot connect to OpenCV Manager");
         }
         else{ Log.i(TAG, "opencv successfull"); 
         System.out.println(java.lang.Runtime.getRuntime().maxMemory()); }
         setContentView(R.layout.frameview);
    }

The problem behind this error is that we are calling opencv dependent function(for example: Mat()) before opencv initialization so its showing error. So you can solve it if you put your opencv function in onManagerConnected() like this :

Log.i(TAG, "OpenCV loaded successfully");
startDisplay();

here, startDisplay() contains my Mat() initialization. The problem is when we start an app then oncreate() function executes first and after that opencv is loaded, so if you put your opencv function in oncreate() then it will show error as opencv is not yet loaded.

I hope this will solve your problem. Best of luck... Stackoverflow Rocks!!! :)