简体   繁体   English

使用OpenCV在Android上显示图像

[英]Display image on Android using OpenCV

I am learning to develop android apps and I am trying to incorporate OpenCV in the apps. 我正在学习开发android应用,并且正在尝试将OpenCV纳入应用中。 I decided to make a simple app that displays an image. 我决定制作一个显示图像的简单应用程序。 The code is given below: 代码如下:

package com.example.first;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import org.opencv.core.Mat;
import org.opencv.highgui.Highgui;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.Canvas;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.webkit.WebView.FindListener;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends Activity{

    Mat m=Highgui.imread("C:/Users/Administrator/Desktop/circle1.png");

}

On checking the logcat the following errors were being displayed: 在检查logcat时,显示以下错误:

E/AndroidRuntime(1310): FATAL EXCEPTION: main E / AndroidRuntime(1310):致命异常:主要

E/AndroidRuntime(1310): java.lang.UnsatisfiedLinkError: Native method not found: org.opencv.highgui.Highgui.imread_1:(Ljava/lang/String;) E / AndroidRuntime(1310):java.lang.UnsatisfiedLinkError:找不到本机方法:org.opencv.highgui.Highgui.imread_1:(Ljava / lang / String;)

E/AndroidRuntime(1310): at org.opencv.highgui.Highgui.imread_1(Native Method) E / AndroidRuntime(1310):位于org.opencv.highgui.Highgui.imread_1(本机方法)

E/AndroidRuntime(1310): at org.opencv.highgui.Highgui.imread(Highgui.java:359) E / AndroidRuntime(1310):位于org.opencv.highgui.Highgui.imread(Highgui.java:359)

E/AndroidRuntime(1310): at com.example.run.MainActivity.(MainActivity.java:26) E / AndroidRuntime(1310):位于com.example.run.MainActivity。(MainActivity.java:26)

E/AndroidRuntime(1310): at java.lang.Class.newInstanceImpl(Native Method) E / AndroidRuntime(1310):位于java.lang.Class.newInstanceImpl(本机方法)

E/AndroidRuntime(1310): at java.lang.Class.newInstance(Class.java:1130) E / AndroidRuntime(1310):位于java.lang.Class.newInstance(Class.java:1130)

E/AndroidRuntime(1310): at android.app.Instrumentation.newActivity(Instrumentation.java:1061) E / AndroidRuntime(1310):位于android.app.Instrumentation.newActivity(Instrumentation.java:1061)

E/AndroidRuntime(1310): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2128) E / AndroidRuntime(1310):位于android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2128)

E/AndroidRuntime(1310): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261) E / AndroidRuntime(1310):位于android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)

E/AndroidRuntime(1310): at android.app.ActivityThread.access$600(ActivityThread.java:141) E / AndroidRuntime(1310):位于android.app.ActivityThread.access $ 600(ActivityThread.java:141)

E/AndroidRuntime(1310): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256) E / AndroidRuntime(1310):位于android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1256)

E/AndroidRuntime(1310): at android.os.Handler.dispatchMessage(Handler.java:99) E / AndroidRuntime(1310):位于android.os.Handler.dispatchMessage(Handler.java:99)

E/AndroidRuntime(1310): at android.os.Looper.loop(Looper.java:137) E / AndroidRuntime(1310):位于android.os.Looper.loop(Looper.java:137)

E/AndroidRuntime(1310): at android.app.ActivityThread.main(ActivityThread.java:5103) E / AndroidRuntime(1310):位于android.app.ActivityThread.main(ActivityThread.java:5103)

E/AndroidRuntime(1310): at java.lang.reflect.Method.invokeNative(Native Method) E / AndroidRuntime(1310):位于java.lang.reflect.Method.invokeNative(本机方法)

E/AndroidRuntime(1310): at java.lang.reflect.Method.invoke(Method.java:525) E / AndroidRuntime(1310):位于java.lang.reflect.Method.invoke(Method.java:525)

E/AndroidRuntime(1310): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) E / AndroidRuntime(1310):位于com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:737)

E/AndroidRuntime(1310): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) E / AndroidRuntime(1310):位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)

E/AndroidRuntime(1310): at dalvik.system.NativeStart.main(Native Method) E / AndroidRuntime(1310):位于dalvik.system.NativeStart.main(本机方法)

What is wrong with this code? 此代码有什么问题?

If you are relatively new to opencv on Android I strongly suggest you start with the sample that comes with the opencv android SDK called image-manipulations. 如果您不熟悉Android上的opencv,我强烈建议您从opencv android SDK附带的示例开始,该示例称为image-manipulations。 There is only one java file ImageManipulationsActivity.java but it has samples of all the typical opencv operations such as Canny etc. It also shows you how to do the async loading of opencv. 只有一个Java文件ImageManipulationsActivity.java,但是它具有所有典型的opencv操作(例如Canny等)的样本。它还向您展示了如何进行opencv的异步加载。 If you can get that to work on your device then you are in a good starting position. 如果您可以在设备上使用它,那么您将处于一个良好的起点。

Note that opencv on Android needs the opencv manager and uses native libraries and so trying to run on an emulator may not be that successful; 请注意,Android上的opencv需要opencv管理器并使用本机库,因此尝试在模拟器上运行可能不会那么成功。 I would recommend testing on your device when developing. 我建议在开发时在您的设备上进行测试。

As others have said, you need to copy the image file over to your device to read it. 正如其他人所说,您需要将图像文件复制到设备上以进行读取。 I use Eclipse DDMS File Explorer and put the files in mnt/sdcard. 我使用Eclipse DDMS File Explorer,并将文件放在mnt / sdcard中。 I then use the following function to load (it could do with more error checking but this should illustrate the idea): 然后,我使用以下函数进行加载(它可以进行更多的错误检查,但这应该可以说明这个想法):

public Mat loadImageFromFile(String fileName) {

    Mat rgbLoadedImage = null;

    File root = Environment.getExternalStorageDirectory();
    File file = new File(root, fileName);

    // this should be in BGR format according to the
    // documentation.
    Mat image = Highgui.imread(file.getAbsolutePath());

    if (image.width() > 0) {

        rgbLoadedImage = new Mat(image.size(), image.type());

        Imgproc.cvtColor(image, rgbLoadedImage, Imgproc.COLOR_BGR2RGB);

        if (DEBUG)
            Log.d(TAG, "loadedImage: " + "chans: " + image.channels()
                    + ", (" + image.width() + ", " + image.height() + ")");

        image.release();
        image = null;
    }

    return rgbLoadedImage;

}

you'll see it comes in as BGR format so I convert to RGB for my purposes. 您会看到它以BGR格式出现,因此我出于自己的目的转换为RGB。

Getting your Mat to then display on Android I think has been covered by previous questions. 我想让您的Mat在Android上显示后,以前的问题已经涵盖了。

“ C:/Users/Administrator/Desktop/circle1.png”是Windows路径,而不是Android路径

please, before typing code blindly into your ide, and then nagging SO with the outcome, 请在盲目地将代码输入您的想法之前,然后将结果SO

have a look the opencv android docs , demos / tutorials 看看opencv android docsdemos / tutorials

you can't use any opencv functionality, before OpenCVLoader.initAsync() finished ( loading the opecv so's) 在OpenCVLoader.initAsync() 完成之前,您不能使用任何opencv功能(因此要加载opecv)

you're not even calling it, so go back at reading the docs. 您甚至都没有调用它,因此请返回阅读文档。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM