C++ 使用OpenCV OnCameraFrame的JNI内存不足崩溃

C++ 使用OpenCV OnCameraFrame的JNI内存不足崩溃,c++,opencv,java-native-interface,segmentation-fault,orb,C++,Opencv,Java Native Interface,Segmentation Fault,Orb,我在我的OnCameraFrame中调用了一个本机方法,该方法检查当前帧的关键点,并尝试找到与模板图像关键点的良好匹配,计算哪个索引图像具有最佳匹配并返回索引。(这是一个物体识别应用程序)。问题是它的工作速度非常慢(3-4fps,完成此方法需要0.3秒),在10-20帧后,它会崩溃,出现SIGSEGV code=1错误。我意识到这可能是一个内存不足的问题,但无法确定代码中的哪个部分占用了所有RAM。希望你能帮忙 JNIEXPORT jint JNICALL Java_org_opencv_sa

我在我的
OnCameraFrame
中调用了一个本机方法,该方法检查当前帧的关键点,并尝试找到与模板图像关键点的良好匹配,计算哪个索引图像具有最佳匹配并返回索引。(这是一个物体识别应用程序)。问题是它的工作速度非常慢(3-4fps,完成此方法需要0.3秒),在10-20帧后,它会崩溃,出现
SIGSEGV code=1
错误。我意识到这可能是一个内存不足的问题,但无法确定代码中的哪个部分占用了所有RAM。希望你能帮忙

JNIEXPORT jint JNICALL  Java_org_opencv_samples_tutorial2_Tutorial2Activity_processImage(
    JNIEnv* env, jlong frameAddress) {


Mat& image = *(Mat*) frameAddress;

cv::OrbFeatureDetector detector(100);
cv::OrbDescriptorExtractor extractor;
std::vector<cv::KeyPoint> queryKeypoints;

detector.detect(image, queryKeypoints);

Mat queryDescriptors;
extractor.compute(image, queryKeypoints, queryDescriptors);

queryDescriptors.convertTo(queryDescriptors, CV_32F);

vector < DMatch > matches;
flannMatcher.match(queryDescriptors, matches);


double max_dist = 0;
double min_dist = 100;

std::vector < DMatch > good_matches;

for (int i = 0; i < matches.size(); i++) {
    if (matches[i].distance <= max(2 * min_dist, 0.02)) {
        good_matches.push_back(matches[i]);
    }
}

int * gmatchIndexes;
gmatchIndexes = new int[good_matches.size()];

for (int i = 0; i < good_matches.size(); i++) {
    gmatchIndexes[i] = -1;
}
for (int kk = 0; kk < good_matches.size(); kk++) {

    gmatchIndexes[good_matches[kk].imgIdx]++;

}


int maxIdx = -1;
for (int i = 0; i < good_matches.size(); i++) {
    if (gmatchIndexes[i] > maxIdx) {
        maxIdx = i;
    }
}

int* p_answer = &maxIdx;
int answer = *p_answer;

//if (gmatchIndexes[maxIdx] > 2) {
image.release();
vector<DMatch>().swap(matches);
vector<DMatch>().swap(good_matches);
delete[] gmatchIndexes;
queryDescriptors.release();

return answer;

}
JNIEXPORT jint JNICALL Java\u org\u opencv\u samples\u tutorial2\u tutorial2 activity\u processImage(
JNIEnv*env,jlong框架地址){
Mat&image=*(Mat*)帧地址;
cv::OrbFeatureDetector检测器(100);
cv::OrbDescriptorExtractor提取器;
std::向量查询点;
检测器。检测(图像、查询点);
Mat queryDescriptors;
compute(image、queryKeypoints、querydescriptor);
queryDescriptors.convertTo(queryDescriptors,CV_32F);
向量匹配;
flannMatcher.match(queryDescriptors,matches);
双最大距离=0;
双最小距离=100;
标准::矢量良好匹配;
for(int i=0;i2){
image.release();
向量()交换(匹配);
vector().swap(良好匹配);
删除[]个Gmatchindex;
queryDescriptors.release();
返回答案;
}

编辑:在我的代码中添加了释放/删除,但现在我遇到了类似以下错误:
@@@ABORTING:dlfree中的堆地址无效
:0:gralloc_module_lock:Cannot lock buffer ID=55438 before register(0x0)

我认为您不能以这种方式使用frameAddress。相反,您应该使用GetByteArrayElements/ReleaseByteArrayElements来获取指向数据的实际指针(并构造适当类型的Mat)。例如:

我在这里看到了一个例子,使用了我传球的方式。但是我会尝试另一种传球方式,尽管我不认为这是导致撞车的原因。对不起,我总是在JNI内部创建垫子,以前从未使用过getNativeObjAddr。