【问题标题】:Native method not found: org.opencv.core.Mat.n_Mat:()J未找到本机方法:org.opencv.core.Mat.n_Mat:()J
【发布时间】:2016-10-20 20:18:06
【问题描述】:

我正在使用原生 android Opencv 3.1.0 库 但总是显示这样的错误

java.lang.UnsatisfiedLinkError:找不到本机方法: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: 致命异常: main 进程:com.example.saya.cameraopencv,PID:21528 java.lang.UnsatisfiedLinkError:找不到本机方法:org.opencv.core.Mat.n_Mat:()J 在 org.opencv.core.Mat.n_Mat(本机方法) 在 org.opencv.core.Mat.(Mat.java:24) 在 com.example.saya.cameraopencv.Hasil.detectEdges(Hasil.java:88) 在 com.example.saya.cameraopencv.Hasil.onCreate(Hasil.java:79) 在 android.app.Activity.performCreate(Activity.java) 在 android.app.Instrumentation.callActivityOnCreate(Instrumentation.java) 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java) 在 android.app.ActivityThread.access$800(ActivityThread.java) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java) 在 android.os.Handler.dispatchMessage(Handler.java) 在 android.os.Looper.loop(Looper.java) 在 android.app.ActivityThread.main(ActivityThread.java) 在 java.lang.reflect.Method.invokeNative(Native Method) 在 java.lang.reflect.Method.invoke(Method.java:515) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java) 在 de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132) 在 dalvik.system.NativeStart.main(Native Method)

【问题讨论】:

    标签: android opencv android-studio


    【解决方案1】:

    代码存在一些问题。在您的onCreate 方法中,您调用OpenCVLoader.initAsync 方法两次,第一次在setContentView 之后,第二次在Log.i(TAG, "Trying to load OpenCV library") 消息之后的if 语句中。您应该只调用一次OpenCVLoader.initAsync 方法,OpenCV4Android SDK 附带的许多示例都通过onResume 方法执行此操作。要更好地了解这是为什么,请查看描述 Activity 生命周期的 this article

    这里的第二个问题是您试图在 OpenCV 完成初始化之前创建一个 Mat 对象。在创建Mat 对象之前,您必须先等待调用 OpenCV 初始化方法的异步任务返回 UIThread。当 OpenCV 初始化线程完成运行时,它会调用onManagerConnected 方法。因此,要解决您的问题,您必须在 onManagerConnected 方法中调用 Mat 初始化代码,以确保仅在 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" />
    

    【讨论】:

    • 非常感谢,您节省了我的时间
    猜你喜欢
    • 2016-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多