使用CallVoidMethod将mat数组从本机代码传递到java代码

使用CallVoidMethod将mat数组从本机代码传递到java代码,java,arrays,java-native-interface,native,mat,Java,Arrays,Java Native Interface,Native,Mat,我想在Java类中传递一个从本机方法计算的数组数组。为此,我想从本机代码调用方法setTarghet来设置每个向量字段。我认为这是个好主意。 这是一个java类: public class struttura { private int _facetCount; public Mat [] VectorTarget; public struttura(int facetCount) { _facetCount = facetCount;

我想在Java类中传递一个从本机方法计算的数组数组。为此,我想从本机代码调用方法setTarghet来设置每个向量字段。我认为这是个好主意。 这是一个java类:

public class struttura {


 private int _facetCount;


    public Mat [] VectorTarget;

    public struttura(int facetCount)
    {
        _facetCount = facetCount;


        VectorTarget = new Mat[facetCount];

    }

    public int getFacetCount()
    {
        return _facetCount;
    }

    public void setTarget (int index,Mat value)
    {
        VectorTarget[index]=value;    

    }
}
这是本机代码

 JNIEXPORT void JNICALL Java_com_example_nonfreejnidemo_NonfreeJNILib_extractorSuTarget(JNIEnv * env, jobject obj, jint nT )
{
   .....

    Mat object[50];

  // read 50 image and put them in object[i]
        for (unsigned int i = 0;i < 50 ;i++) {
            object[i] = imread( files[i], CV_LOAD_IMAGE_GRAYSCALE );
        }

        //Detect the keypoints using SURF Detector
        int minHessian = 500;

        SurfFeatureDetector detector( minHessian );
        std::vector<KeyPoint> kp_object[nT];


        for (unsigned int i = 0;i < nT; i++)
        {
            detector.detect( object[i], kp_object[i] );
        }


        //Calculate descriptors (feature vectors)
        SurfDescriptorExtractor extractor;

        Mat des_object[nT];

        for (unsigned int i = 0;i < nT; i++)
        {
             extractor.compute( object[i], kp_object[i], des_object[i] );

        }
        //-----------------------------------------------------------------------------------------------
        // now begin my problem
    // i want to call method setTarget from java code to map des_object on VectorTarget 
    // and use it on java code.
    // i try something like this but i have some  errors.
    // i now that it is not correct, i do not know how write it.

    for (int index=0; index <50; index++)
    {

               jlong        y  =    (jlong)des_object[index] ;
               jclass cls = env->GetObjectClass(obj);
               jmethodID methodId = env->GetMethodID( cls, "setTarget", "(IJ)V");
               env->CallVoidMethod(obj, methodId,index,y );

     }
        //-----------------------------------------------------------------------------------------------
JNIEXPORT void JNICALL Java_com_示例_nonfreejnidemo_NonfreeJNILib_提取器目标(JNIEnv*env,jobject obj,jint)
{
.....
Mat对象[50];
//阅读50张图片并将其放入对象[i]
for(无符号整数i=0;i<50;i++){
对象[i]=imread(文件[i],CV\u加载\u图像\u灰度);
}
//使用SURF检测器检测关键点
int minHessian=500;
表面特征检测器(minHessian);
std::向量kp_对象[nT];
for(无符号整数i=0;iGetMethodID(cls,“setTarget”,IJ)V);
env->CallVoidMethod(对象,方法ID,索引,y);
}
//-----------------------------------------------------------------------------------------------
我想从java代码中调用方法setTarget来映射VectorTarget上的desu对象,并在java代码中使用它。 我尝试过这样的方法,但我有一些错误。 我知道这是不对的,我不知道怎么写
请帮助我。

< P>你的概念有一个流——你不能通过类的C++实例<强>垫> /St>作为类的java对象<强> Mat < /St>>/P> 另一方面,您不需要调用Java方法来设置Java对象数组的元素

因此,您的循环可以简单地如下所示

jclass matClass = static_cast<jclass>(env->FindClass("com/example/Mat");
jmethodID matConstructor = env->GetMethodID(matClass, "<init>", "([I)V");
for (int index=0; index<50; index++)
{
    jobject jMatObject = env->NewObject(matClass, matConstructor, des_object[index]);
    env->SetObjectArrayElement( arr, i, jMatObject);
    env->DeleteLocalRef(jMatObject);
}

和C++中,

extern "C" JNIEXPORT void JNICALL Java_com_example_nonfreejnidemo_NonfreeJNILib_extractorSuTarget(JNIEnv * env, jobject obj, jint nT )
{
   .....

    Mat object[50];

  // read 50 image and put them in object[i]
        for (unsigned int i = 0;i < 50 ;i++) {
            object[i] = imread( files[i], CV_LOAD_IMAGE_GRAYSCALE );
        }

        //Detect the keypoints using SURF Detector
        int minHessian = 500;

        SurfFeatureDetector detector( minHessian );
        std::vector<KeyPoint> kp_object[nT];


        for (unsigned int i = 0;i < nT; i++)
        {
            detector.detect( object[i], kp_object[i] );
        }

        //Calculate descriptors (feature vectors)
        SurfDescriptorExtractor extractor;

        Mat* des_object = new Mat[nT]();

        for (unsigned int i = 0;i < nT; i++)
        {
             extractor.compute( object[i], kp_object[i], des_object[i] );

        }
        jclass cls = env->GetObjectClass(obj);
        jmethodID methodId = env->GetMethodID( cls, "setTarget", "(J)V");
        env->CallVoidMethod(obj, methodId, (jlong)des_object);

}
extern“C”JNIEXPORT void JNICALL Java\u com\u示例\u nonfreejnidemo\u NonfreeJNILib\u提取器目标(JNIEnv*env,jobject obj,jint)
{
.....
Mat对象[50];
//阅读50张图片并将其放入对象[i]
for(无符号整数i=0;i<50;i++){
对象[i]=imread(文件[i],CV\u加载\u图像\u灰度);
}
//使用SURF检测器检测关键点
int minHessian=500;
表面特征检测器(minHessian);
std::向量kp_对象[nT];
for(无符号整数i=0;iGetObjectClass(obj);
jmethodID=env->GetMethodID(cls,“setTarget”,J)V);
env->CallVoidMethod(对象,方法ID,(jlong)des_对象);
}

谢谢你回复我。我不实用,很抱歉我的基本问题。我不明白一些事情:1)当你写:env->FindClass(“com/example/Mat”)时,你是指我的包中我的类(struttura)的路径?因此:com/example/nonfreejnidemo/struttura 2)如何修改java类的构造函数?你能帮我吗?3) 我如何为mat数组重写env->GetMethodID(matClass,“,”([i)V”);非常感谢。
FindClass
是为mat类(VectorTarget的元素类)。对于构造函数也是一样:它从
des_object
vector中获取一个对象,并创建一个对象放置在
VectorTarget
中。或者可能我没有正确理解存储这些本机对象的目的(它们来自OpenCV?)在Java对象中。在您将这些描述符存储在
VectorTarget
中之后,您将如何处理这些描述符?我可能有很多错误。我编写了一个用C++和opencv编写的程序,通过网络摄像头读取存储在HD50上的图像,并将其与网络摄像头捕获的每一帧进行比较。我使用了SURF for matc的算法图像处理。目的是每次网络摄像头看到的路标都能从我预装的50幅图像中识别出来。一切正常。我在Android上移植这个应用程序时遇到的问题。计算描述符SURF的方法必须保留在C++中。为此,我使用了JNI。因此,程序的第一部分,本机代码读取50个图像标记,计算它们的描述符,并将其传递到Java类(我称之为structura)中然后到Java代码,我打开网络摄像头,为每一帧捕获到本机代码的步骤,计算每一帧的描述符,并与struttura类中包含的所有描述符进行比较。当我找到帧和图片之间的匹配时,我会执行其他操作…而在本机代码中,我不能有全局变量have必须存储在java结构中。您不知道如何通过更高效的移植来实现这一点吗?
extern "C" JNIEXPORT void JNICALL Java_com_example_nonfreejnidemo_NonfreeJNILib_extractorSuTarget(JNIEnv * env, jobject obj, jint nT )
{
   .....

    Mat object[50];

  // read 50 image and put them in object[i]
        for (unsigned int i = 0;i < 50 ;i++) {
            object[i] = imread( files[i], CV_LOAD_IMAGE_GRAYSCALE );
        }

        //Detect the keypoints using SURF Detector
        int minHessian = 500;

        SurfFeatureDetector detector( minHessian );
        std::vector<KeyPoint> kp_object[nT];


        for (unsigned int i = 0;i < nT; i++)
        {
            detector.detect( object[i], kp_object[i] );
        }

        //Calculate descriptors (feature vectors)
        SurfDescriptorExtractor extractor;

        Mat* des_object = new Mat[nT]();

        for (unsigned int i = 0;i < nT; i++)
        {
             extractor.compute( object[i], kp_object[i], des_object[i] );

        }
        jclass cls = env->GetObjectClass(obj);
        jmethodID methodId = env->GetMethodID( cls, "setTarget", "(J)V");
        env->CallVoidMethod(obj, methodId, (jlong)des_object);

}