【问题标题】:Display image on Android using OpenCV使用 OpenCV 在 Android 上显示图像
【发布时间】:2026-02-14 15:10:02
【问题描述】:

我正在学习开发 android 应用程序,我正在尝试将 OpenCV 整合到应用程序中。我决定制作一个显示图像的简单应用程序。代码如下:

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

}

在检查 logcat 时显示以下错误:

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

E/AndroidRuntime(1310): java.lang.UnsatisfiedLinkError: Native 方法 未找到:org.opencv.highgui.Highgui.imread_1:(Ljava/lang/String;)

E/AndroidRuntime(1310):在 org.opencv.highgui.Highgui.imread_1(Native 方法)

E/AndroidRuntime(1310): 在 org.opencv.highgui.Highgui.imread(Highgui.java:359)

E/AndroidRuntime(1310): 在 com.example.run.MainActivity.(MainActivity.java:26)

E/AndroidRuntime(1310): 在 java.lang.Class.newInstanceImpl(Native 方法)

E/AndroidRuntime(1310): 在 java.lang.Class.newInstance(Class.java:1130)

E/AndroidRuntime(1310): 在 android.app.Instrumentation.newActivity(Instrumentation.java:1061)

E/AndroidRuntime(1310): 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2128)

E/AndroidRuntime(1310): 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)

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

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

E/AndroidRuntime(1310): 在 android.os.Handler.dispatchMessage(Handler.java:99)

E/AndroidRuntime(1310): 在 android.os.Looper.loop(Looper.java:137)

E/AndroidRuntime(1310): 在 android.app.ActivityThread.main(ActivityThread.java:5103)

E/AndroidRuntime(1310): 在 java.lang.reflect.Method.invokeNative(Native Method)

E/AndroidRuntime(1310): 在 java.lang.reflect.Method.invoke(Method.java:525)

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

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

E/AndroidRuntime(1310): 在 dalvik.system.NativeStart.main(Native 方法)

这段代码有什么问题?

【问题讨论】:

  • 你能让一个 hello-world 应用显示图像吗? (比如说,* 的标志?)
  • @18446744073709551615 在activity_main.xml文件中,当我在图形布局中查看它时,我可以看到图像,但是当我在模拟器上运行它时它不显示图像。
  • 如果您无法编写显示图像的应用程序,这是一个不同的问题,与 opencv 无关。 (欢迎您在 Google 上搜索示例或在此处询问您是否遇到了其他人没有遇到过的问题。)一旦您设法显示图像,您必须将 Mat 转换为 Android 本身可以理解的东西(例如,制作一个位图可绘制,或将 Mat 保存为 png)并显示它。
  • @18446744073709551615 检查了logcat中的错误,它说找不到函数imread()。所以它似乎与OpenCV有关。

标签: java android opencv


【解决方案1】:

如果您对 Android 上的 opencv 比较陌生,我强烈建议您从 opencv android SDK 附带的名为 image-manipulations 的示例开始。只有一个 java 文件 ImageManipulationsActivity.java 但它包含所有典型的 opencv 操作的示例,例如 Canny 等。它还向您展示了如何进行 opencv 的异步加载。如果你可以让它在你的设备上工作,那么你就处于一个很好的起点。

请注意,Android 上的 opencv 需要 opencv 管理器并使用本机库,因此尝试在模拟器上运行可能不会那么成功;我建议在开发时在您的设备上进行测试。

正如其他人所说,您需要将图像文件复制到您的设备上才能读取它。我使用 Eclipse DDMS 文件资源管理器并将文件放在 mnt/sdcard 中。然后我使用以下函数来加载(它可以做更多的错误检查,但这应该说明这个想法):

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;

}

您会看到它以 BGR 格式出现,因此我将其转换为 RGB。

让你的 Mat 在 Android 上显示我认为之前的问题已经涵盖了。

【讨论】:

  • 很好的答案,但只是为了记录,android 不需要 OpenCV 管理器。您可以在您的 apk 中包含设备的所有 opencv 本机库,然后使用 initDebug() 告诉您的程序查看那里。但我读过使用带有 initAsync() 的 OpenCV 管理器是首选方式。
【解决方案2】:

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

【讨论】:

  • 那么我应该做的编辑是什么?将图像复制到可绘制的res文件夹中,然后尝试给出其路径?试过了,还是不行。
  • 天啊!您应该首先使用adb push 并将文件传送到(虚拟或真实)设备。当你设法做到这一点时,你就会知道路径。
【解决方案3】:

拜托,在盲目地在你的 ide 中输入代码,然后用结果唠叨 SO 之前,

看看opencv android docs , demos / tutorials

在 OpenCVLoader.initAsync()完成(加载 opecv so's)之前,您不能使用任何 opencv 功能

你甚至没有调用它,所以回去阅读文档。

【讨论】:

  • 就是这样。我做了并且没有找到任何可能有帮助的东西。冷静下来并帮助伴侣,如果您不能,请不要评论/回答并浪费时间。什么都不感谢。
  • 就像我说的,我检查过了。没有找到解决办法。