Возврат объекта Mat из нативного кода в Java в OpenCV - PullRequest
9 голосов
/ 30 марта 2012

У меня есть приложение OpenCV Android. Большая часть его кода на Java, но у меня есть одна функция, которая находится в C. Функция получает объект Mat и возвращает новый.

Мой вопрос: как мне вернуть Mat из нативного кода в Java? Не удалось найти ни одного примера.

Спасибо.

Ответы [ 2 ]

23 голосов
/ 07 апреля 2012

Сегодня мне пришлось вернуть мат из родного кода. Я начал с "Tutorial 2 Advanced - 2. Mix Java + Native OpenCV", он уже передает два объекта Mat (изображения, снятые с камеры) в собственный код. Но я хотел вернуть извлеченную функцию, поэтому добавил к подписи jlong addrDescriptor:

extern "C" {
JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial4_Sample4View_FindFeatures(JNIEnv* env, jobject thiz, jlong addrGray, jlong addrRgba, jlong addrDescriptor)
{
    Mat* pMatGr=(Mat*)addrGray;
    Mat* pMatRgb=(Mat*)addrRgba;
    Mat* pMatDesc=(Mat*)addrDescriptor;
    vector<KeyPoint> v;

    //OrbFeatureDetector detector(50);
    OrbFeatureDetector detector;
    OrbDescriptorExtractor  extractor;
    detector.detect(*pMatGr, v);
    extractor.compute( *pMatGr, v, *pMatDesc );
    circle(*pMatRgb, Point(100,100), 10, Scalar(5,128,255,255));
    for( size_t i = 0; i < v.size(); i++ ) {
        circle(*pMatRgb, Point(v[i].pt.x, v[i].pt.y), 10, Scalar(255,128,0,255));
    }
    }
}

В Java-части я добавил мат

private Mat descriptor;
descriptor = new Mat();

Метод getNativeObjAddr() добивается цели. Мат выделяется в Java, а его адрес передается в собственный код, поэтому явного возврата нет.

FindFeatures(mGraySubmat.getNativeObjAddr(), mRgba.getNativeObjAddr(), descriptor.getNativeObjAddr());
Log.i("desc:"  , descriptor.dump());

Мат был заполнен необходимыми данными и сразу же доступен в коде Java после возврата вызова JNI.

Где-то еще в коде Мат выпущен:

if ( descriptor != null) 
  descriptor.release();
descriptor = null;
3 голосов
/ 16 марта 2018

в C ++

jlong funC(){
Mat *mat = new Mat();
//...
return (jlong)mat;
}

в Java:

long = addr;// addr is return from c method funC()
Mat mat = new Mat(addr);

Внимание: Вы должны создать новый Mat () в C, если код: Mat mat (); память объекта mat будет собираться после завершения funC ().

...