【发布时间】:2012-03-30 00:46:05
【问题描述】:
我有一个 OpenCV Android 应用程序。它的大部分代码都是用 Java 编写的,但我有 C 中的一个函数。 该函数获取一个 Mat 对象并返回一个新对象。
我的问题是如何将 Mat 从本机代码返回给 Java? 找不到任何例子。
谢谢。
【问题讨论】:
我有一个 OpenCV Android 应用程序。它的大部分代码都是用 Java 编写的,但我有 C 中的一个函数。 该函数获取一个 Mat 对象并返回一个新对象。
我的问题是如何将 Mat 从本机代码返回给 Java? 找不到任何例子。
谢谢。
【问题讨论】:
今天我不得不从本机代码返回一个 Mat。我从“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 部分我添加了 Mat
private Mat descriptor;
descriptor = new Mat();
getNativeObjAddr() 方法可以解决问题。 Mat 是在 java 中分配的,它的地址被传递给本地代码,因此没有任何显式返回。
FindFeatures(mGraySubmat.getNativeObjAddr(), mRgba.getNativeObjAddr(), descriptor.getNativeObjAddr());
Log.i("desc:" , descriptor.dump());
Mat 填充了所需的数据,在 JNI 调用返回后可在 java 代码中直接访问。
Mat 被释放的代码中的其他地方:
if ( descriptor != null)
descriptor.release();
descriptor = null;
【讨论】:
void medianBlur(const Mat& src, Mat& dst, int ksize) 您需要通过引用处理来调用它。试试&processing。或者定义为Mat& processing(image.size(), CV_8UC3);
Mat &dst,那么你应该在你的java代码中声明它,并将它添加到JNI方法的调用中,就像你添加image一样。
Somwhere else in the code the Mat is released:是什么意思
在 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);
注意:你必须在 C 中 new Mat(),如果你的代码是: Mat mat();当 funC() 结束时,mat 对象内存将被收集。
【讨论】: