Hammad urRehman
Hammad urRehman

Reputation: 51

Return array of Mat from jni to java

First i am a new user to Stackoverflow I am SORY for any mistake in this question. I have done my best but havent solved my problem please guide.

I have searched a lot before asking this question but havent found the answer. I have a c++ code where i do some image processing and get 2 2d-arrays and 1 1d-array on output(String[][], int[][], Mat[]). I am done returning String and int array to java but not able to return Mat[] to java. To return Mat[] array to java by Now what i have done is given below.

jclass cls = env->FindClass("org/opencv/core/Mat");
jmethodID jMatCons = env->GetMethodID(cls,"<init>","()V");

// Call back constructor to allocate a new instance
jobjectArray newMatArr = env->NewObjectArray(appWords.size(), cls, 0);
jobject jMat = env->NewObject(cls, jMatCons);

for (int k=0; k< appWords.size(); k++){
    env->SetObjectArrayElement(newMatArr, k, jMat);
 //   nativeBufImgs[k] = appWords[k];
}

The code pasted above returns a Mat[] array to java but empty. To solve my problem I have checked these questions how to return array of Mat from JNI to Java but it didnt solved my problem. I have also duplicated this link for my Mat[] problem but no fruit Getting keypoint back from native code In the code pasetd above i think the problem is i haven't put the method signature for Mat in this line

jmethodID jMatCons = env->GetMethodID(cls,"","()V");

So please guide me for this. or any other solution will be appreciated

Upvotes: 1

Views: 2155

Answers (2)

Ahmad Slo
Ahmad Slo

Reputation: 39

I'm a bit late. However, the following code shows how to create Mat array in C++ and return it back to java.

JNIEXPORT jobjectArray JNICALL Java_de_dsi_decoder_Helper_processFrame (JNIEnv * env, jobject)
{
vector<Mat> images=fill_images();//fill it with your Mats
//copy from native to java

    jclass matclass = env->FindClass("org/opencv/core/Mat");
    jmethodID jMatCons = env->GetMethodID(matclass,"<init>","()V");
    jmethodID getPtrMethod = env->GetMethodID(matclass, "getNativeObjAddr", "()J");

    // Call back constructor to allocate a new instance
    jobjectArray newMatArr = env->NewObjectArray(images.size(), matclass, 0);


    for (int i=0; i< images.size(); i++){
        jobject jMat = env->NewObject(matclass, jMatCons);
        Mat & native_image= *(Mat*)env->CallLongMethod(jMat, getPtrMethod);
        native_image=images[i];

        env->SetObjectArrayElement(newMatArr, i, jMat);
    }

    return newMatArr;
}

Upvotes: 1

Daniel Moraes
Daniel Moraes

Reputation: 143

Check this. It worked for me.

From Java, you create a Mat object and pass it as a pointer.

Mat mat_object = new Mat();
nativeFunction(mat_object.getNativeObjAddr());

From C++, you cast the pointer to cv::Mat.

cv::Mat& mat_object  = *(cv::Mat*) mat_pointer;

// do something with the mat

Upvotes: 1

Related Questions