4

In Java side I have

List<Mat> arystrdimages = new ArrayList<Mat>();

subsequently the images read from a folder in external directory are added into the list

for(File f : strdimgs)
{       
    Mat tempimg = Highgui.imread(f.getAbsolutePath(), CvType.CV_8UC1);
    arystrdimages.add(tempimg);
}

In Native jni side I want to access arystrdimages by its reference.

For a single Mat object, we can do it by calling getNativeObjAddr method, i.e in opencv4android examples for a Mat object the accessing in native side is done as shown below

Java

private Mat mRgba;

call to native side

CallNative(mRgba.getNativeObjAddr());

In Native side

JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial2_Tutorial2Activity_CallNative(JNIEnv *env, jobject thiz, jlong addrRgba1)
{
     Mat& mRgb = *(Mat*)addrRgba1;
}

How to do this for List<Mat> objects?.

EDIT: Implementation of your suggested solution

Java side

int elems = arystrdimages.size();
Log.v("Matobjdata", "number of Matobject read = " + elems);
//Log.v("Matobjdata", "from native = " + ans);
long[] tempobjadr = new long[elems]; 
for (int i=0; i<elems; i++)
{
    Mat tempaddr = arystrdimages.elementAt(i);
    tempobjadr[i] = tempaddr.getNativeObjAddr();
}

Log.v("Matobjdata", "addresselementsinlong arrray = " + tempobjadr.length);
int ans = TrainDescriptors(tempobjadr); // Call to native function
Log.v("Matobjdata", "from native = " + ans);

Native side

JNIEXPORT jint JNICALL Java_org_opencv_samples_tutorial2_Tutorial2Activity_TrainDescriptors(JNIEnv *env, jobject trainobject, jlongArray traindataaddr)
{
    vector<Mat> trainimgs;
    jsize a_len = env->GetArrayLength(traindataaddr);
    jlong *traindata = env->GetLongArrayElements(traindataaddr, 0);

    for(int k=0; k<a_len; k++)
    {
        Mat & newimage=*(Mat*)traindata[k];
        trainimgs.push_back(newimage);
    }
    // Do the required manipulation on the images; 
    env->ReleaseLongArrayElements(traindataaddr, traindata, 0);

    return a_len;
}
1
  • @manuell Thanks for your help, i have not implemented your complete solution yet. I just did half of it, it was working fine (i.e i checked till GetArrayLength, it was giving the correct result). I will try your complete it now and post the answer. Commented Nov 26, 2013 at 12:25

1 Answer 1

6

You could build, in Java, an array of long values (getNativeObjAddr() results for all the Mat) and call a native function passing the array.

In JNI, you could access all the long values with GetArrayLength and GetLongArrayElements (which returns a jlong* to the first element).

Use ReleaseLongArrayElements when done.

Sign up to request clarification or add additional context in comments.

3 Comments

Your suggestion is working, i have updated the code in JNI. Thanks a lot :-)
You'a welcome. Some redundant code in your native func (a_len and traindata). I don't know how the C++ Mat is implemented, but do you intend the "required manipulations" be visible to the Java side? Are they?
ya, there are few redundant lines, il have to clean those. At the moment its not required for manipulations to be visible in java side. it should not be much difficult if it has to be.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.