2016-10-20 3 views
1

Я использую родной андроид OpenCV 3.1.0 библиотеки но всегда показывает ошибку, как этотNative метода не найден: org.opencv.core.Mat.n_Mat :() J

java.lang.UnsatisfiedLinkError: Native method not found: org.opencv.core.Mat.n_Mat:()J

Это мой код

package com.example.saya.cameraopencv; 

public class Hasil extends AppCompatActivity{ 

private TextView coba; 
private ImageView gambarskrg; 
private Mat rgba; 

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");   
      } break; 
      default: 
      { 
       super.onManagerConnected(status); 
      } break; 
     } 
    } 
}; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.hasil_activity); 
    OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_1_0, this, mOpenCVCallBack); 
    Bundle i = getIntent().getExtras(); 

    gambarskrg = (ImageView) findViewById(R.id.gambar); 

    String gambar = Environment.getExternalStorageDirectory()+ "/Coba/Coba_1476987074709.jpg"; 

    Bitmap bmp = BitmapFactory.decodeFile(gambar); 

    Log.i(TAG, "Trying to load OpenCV library"); 
    if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_1_0, this, mOpenCVCallBack)) 
    { 
     Log.e(TAG, "Cannot connect to OpenCV Manager"); 
    } 
    else { 
     Log.e(TAG, "Berhasil"); 
     try { 
      detectEdges(bmp); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

private void detectEdges(Bitmap bmp){ 
    Mat rgba = new Mat(); 
    Utils.bitmapToMat(bmp, rgba); 

    Mat edges = new Mat(rgba.size(), CvType.CV_8UC4); 
    Imgproc.cvtColor(rgba, edges, Imgproc.COLOR_RGBA2GRAY, 4); 
    Imgproc.Canny(edges, edges, 80, 100); 

    Bitmap resultBitmap = Bitmap.createBitmap(edges.cols(), edges.rows(), Bitmap.Config.ARGB_8888); 
    Utils.matToBitmap(edges, resultBitmap); 
    int nh = (int) (resultBitmap.getHeight() * (512.0/resultBitmap.getWidth())); 
    Bitmap scaled = Bitmap.createScaledBitmap(resultBitmap, 512, nh, true); 
    gambarskrg.setImageBitmap(scaled); 
} 

}

и этого LogCat

10-21 04:02:32.333 21528-21528/com.example.saya.cameraopencv E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.saya.cameraopencv, PID: 21528 java.lang.UnsatisfiedLinkError: Native method not found: org.opencv.core.Mat.n_Mat:()J at org.opencv.core.Mat.n_Mat(Native Method) at org.opencv.core.Mat.(Mat.java:24) at com.example.saya.cameraopencv.Hasil.detectEdges(Hasil.java:88) at com.example.saya.cameraopencv.Hasil.onCreate(Hasil.java:79) at android.app.Activity.performCreate(Activity.java) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java) at android.app.ActivityThread.access$800(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java) at android.os.Handler.dispatchMessage(Handler.java) at android.os.Looper.loop(Looper.java) at android.app.ActivityThread.main(ActivityThread.java) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java) at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132) at dalvik.system.NativeStart.main(Native Method)

ответ

3

Есть несколько проблем с кодом. В методе onCreate вы вызываете метод OpenCVLoader.initAsync дважды, первый раз после setContentView, второй раз в операторе if после сообщения Log.i(TAG, "Trying to load OpenCV library"). Вы должны только вызвать метод OpenCVLoader.initAsync один раз, многие из примеров, которые поставляются с OpenCV4Android SDK, делают это с помощью метода onResume. Чтобы лучше понять, почему это так, посмотрите this article, в котором описывается жизненный цикл активности.

Вторая проблема заключается в том, что вы пытаетесь создать объект Mat до того, как OpenCV завершит инициализацию. Сначала вы должны дождаться асинхронной задачи, которая вызывает метод инициализации OpenCV, чтобы вернуться обратно в UIThread, прежде чем создать объект Mat. Когда поток инициализации OpenCV завершен, он вызывает метод onManagerConnected. Поэтому, чтобы исправить вашу проблему, вы должны вызвать код инициализации Mat в методе onManagerConnected, чтобы убедиться, что он вызывается только после завершения инициализации кода OpenCV. Вот пример того, как это должно выглядеть:

private Bitmap bmp; 
final String TAG = "Hello World";  

private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) { 
    @Override 
    public void onManagerConnected(int status) { 
     switch (status) { 
      case LoaderCallbackInterface.SUCCESS: { 
       Log.i(TAG, "OpenCV loaded successfully"); 
       try { 
        detectEdges(bmp); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
      break; 
      default: { 
       super.onManagerConnected(status); 
      } 
      break; 
     } 
    } 
}; 

@Override 
public void onResume() { 
    super.onResume(); 
    if (!OpenCVLoader.initDebug()) { 
     Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization"); 
     OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_1_0, this, mLoaderCallback); 
    } else { 
     Log.d(TAG, "OpenCV library found inside package. Using it!"); 
     mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS); 
    } 
} 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.hasil_activity); 
    Bundle i = getIntent().getExtras(); 
    String gambar = Environment.getExternalStorageDirectory()+ "/Coba/Coba_1476987074709.jpg"; 
    bmp = BitmapFactory.decodeFile(gambar); 
} 

private void detectEdges(Bitmap bmp){ 
    Mat rgba = new Mat(); 
    Utils.bitmapToMat(bmp, rgba); 

    Mat edges = new Mat(rgba.size(), CvType.CV_8UC4); 
    Imgproc.cvtColor(rgba, edges, Imgproc.COLOR_RGBA2GRAY, 4); 
    Imgproc.Canny(edges, edges, 80, 100); 

    Bitmap resultBitmap = Bitmap.createBitmap(edges.cols(), edges.rows(), Bitmap.Config.ARGB_8888); 
    Utils.matToBitmap(edges, resultBitmap); 
    int nh = (int) (resultBitmap.getHeight() * (512.0/resultBitmap.getWidth())); 
    Bitmap scaled = Bitmap.createScaledBitmap(resultBitmap, 512, nh, true); 
    ((ImageView) findViewById(R.id.gambar)).setImageBitmap(scaled); 
} 

Кроме того, поскольку вы читаете изображения из внешней памяти, вам, возможно, придется просить разрешения пользователя для чтения из памяти в зависимости от версии Android вы ориентируетесь. Вы делаете это, добавляя следующий код к своему манифестому Android:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 
+1

Большое спасибо, вы экономите свое время – Taufiq

Смежные вопросы