Как вернуть изображение из OpenCV и отобразить его в коде Android Java? - PullRequest
5 голосов
/ 23 марта 2011

Я пытаюсь нарисовать фигуру, используя библиотеку OpenCV в собственном коде (то есть в папке jni в приложении Android), и вызываю собственный метод, чтобы вернуть изображение в код Java и отобразить его.

Как это можно сделать? Я не могу найти простое приложение для Android, использующее OpenCV. Я также настроил среду и образцы для Android, использующие OpenCV, такие как cvcamera, калибровки работают нормально. Они использовали 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.

Ответы [ 2 ]

5 голосов
/ 24 марта 2011

Вместо этого вы можете использовать JavaCV. Это дает полный доступ к OpenCV в Java. Нет необходимости в JNI, SWIG или NDK ...

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

3 голосов
/ 15 августа 2012

Вы можете передать bytearray или intarray в 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;

}

Пример кода можно найти в этой статье Как выполнять обработку изображений в реальном времени в Android с помощью OpenCV.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...