【问题标题】:How do I return an image from OpenCV and display it in Android Java code?如何从 OpenCV 返回图像并在 Android Java 代码中显示?
【发布时间】:2011-07-21 01:22:29
【问题描述】:

我正在尝试使用本机代码中的 OpenCV 库(即在 Android 应用程序的 jni 文件夹中)绘制一个形状,并调用本机方法将图像返回到 Java 代码并显示它。

如何做到这一点?我找不到使用 OpenCV 的简单 Android 应用程序。我也设置了环境,使用 OpenCV(如 cvcamera)为 Android 提供的示例,校准运行良好。他们将 SWIG 用于 JNI 接口。 SWIG 是强制性的吗?我没有使用 SWIG。我尝试了很多,现在仍在尝试。

在Java中,代码是这样的:

public class HelloJni extends Activity
{
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new ShapeView(this));
    }

    static {
        System.loadLibrary("hello-jni");
    }
}


class ShapeView extends View
{
    private Bitmap mBitmap;

    private static native Object drawingShape();

    public ShapeView(Context context) {
        super(context);
    }

    protected void onDraw(Canvas canvas) {
        mBitmap = (Bitmap) drawingShape();
        canvas.drawBitmap(mBitmap, 0, 0, null);
    }
}

而在原生 jni 类中,

#include "ShapeView.h"
#include <string.h>
#include <jni.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>


JNIEXPORT jobject JNICALL Java_ShapeView_drawingShape
(JNIEnv *env, jclass obj) {

    IplImage* img = cvCreateImage(cvSize(300, 300), IPL_DEPTH_8U, 3);

    cvRectangle(img, cvPoint(100, 100), cvPoint(200, 200), cvScalar(255, 0, 0), 1);
    cvCircle(img, cvPoint(100, 100), 20, cvScalar(0, 255, 0), 1);

    return (jobject)img;
}

我使用 ndk-build 编译了本机代码。 .so 文件还创建并 安装没有任何错误。在Java代码中也没有任何错误。

当我在 AVD 中运行应用程序时,我只能看到一个黑屏,它会在几秒钟内消失。

代码有什么错误?

如果 SWIG 是强制性的,怎么做?我对 OpenCV 和 SWIG 了解不多。

【问题讨论】:

    标签: android image image-processing opencv


    【解决方案1】:

    您可以改用 JavaCV。它提供了对 Java 中 OpenCV 的完全访问权限。不需要 JNI、SWIG 或 NDK...

    http://code.google.com/p/javacv/

    【讨论】:

    • 但你提到的 javacv 只包含 C 接口的 java 包装器,而不包含 C++ 的包装器。.. 是否建议使用 javacv?
    • 始终可以直接使用 JavaCPP(JavaCV 所基于)来访问 C++ API。这只是多一点工作,但没有原始 JNI 或 SWIG 那么多
    • 仅供参考,JavaCV 的较新版本现在支持仅通过 C++ API 提供的功能。
    【解决方案2】:

    您可以将bytearrayintarray 传递给JNI,并使用GetByteArrayElements() 作为指针访问数组。直接修改数组数据,最后释放。 Java代码文件中的数组数据应该改变了。

    extern "C"
    jboolean
    Java_my_project_MyRealTimeImageProcessing_CameraPreview_ImageProcessing(
        JNIEnv* env, jobject thiz,
        jint width, jint height,
        jbyteArray NV21FrameData, jintArray outPixels)
    {
    jbyte * pNV21FrameData = env->GetByteArrayElements(NV21FrameData, 0);
    jint * poutPixels = env->GetIntArrayElements(outPixels, 0);
    
    if ( mCanny == NULL )
    {
        mCanny = new Mat(height, width, CV_8UC1);
    }
    
    Mat mGray(height, width, CV_8UC1, (unsigned char *)pNV21FrameData);
    Mat mResult(height, width, CV_8UC4, (unsigned char *)poutPixels);
    IplImage srcImg = mGray;
    IplImage CannyImg = *mCanny;
    IplImage ResultImg = mResult;
    
    cvCanny(&srcImg, &CannyImg, 80, 100, 3);
    cvCvtColor(&CannyImg, &ResultImg, CV_GRAY2BGRA);
    
    env->ReleaseByteArrayElements(NV21FrameData, pNV21FrameData, 0);
    env->ReleaseIntArrayElements(outPixels, poutPixels, 0);
    return true;
    

    }

    示例代码可以在这篇文章How to do real time image processing in Android using OpenCV?找到。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-17
      • 2013-09-14
      • 1970-01-01
      • 2012-08-10
      • 1970-01-01
      • 1970-01-01
      • 2015-08-24
      • 1970-01-01
      相关资源
      最近更新 更多