Returning Mat object from native code to java in OpenCV

前端 未结 2 813
庸人自扰
庸人自扰 2020-12-03 02:04

I have an OpenCV Android app. Most of its code is in Java but I have one function that is in C. The function gets a Mat object and returns a new one.

My question is

相关标签:
2条回答
  • 2020-12-03 02:41

    in C++

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

    in java:

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

    Attention: You must new Mat() in C,if you code is : Mat mat();mat object memory will be collect when funC() end.

    0 讨论(0)
  • 2020-12-03 02:57

    Today I had to return a Mat from native code. I started with "Tutorial 2 Advanced - 2. Mix Java+Native OpenCV" it already passes two Mat (Images captured from camera) objects to the native code. But I wanted to return extracted feature, thus I added jlong addrDescriptor to the signature:

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

    In the java part I added the Mat

    private Mat descriptor;
    descriptor = new Mat();
    

    The method getNativeObjAddr() does the trick. The Mat is allocated in java and its address is passed to the native code, thus there isn't any explicit returning.

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

    The Mat was filled with the required data and is directly accessible in the java code after the JNI invokation returns.

    Somwhere else in the code the Mat is released:

    if ( descriptor != null) 
      descriptor.release();
    descriptor = null;
    
    0 讨论(0)
提交回复
热议问题