2015-01-18 5 views
0

OnCameraFrame의 네이티브 메소드를 호출하여 현재 프레임의 키포인트를 확인하고 템플릿 이미지의 키포인트와 일치하는 항목을 찾고 가장 잘 일치하는 인덱스 이미지를 계산하고 인덱스를 반환합니다 . (그것은 객체 인식 앱입니다). 문제는 실제로 느린 것입니다 (3-4 fps, 0.3 초 ​​소요). 10-20 프레임 후에는 SIGSEGV code=1 오류로 인해 충돌합니다. 이것은 아마도 Out of Memory 문제이지만, 코드의 어느 부분이 모든 RAM을 먹는지 알 수는 없습니다. 당신이 도울 수 있기를 바랍니다.OpenCV OnCameraFrame을 사용하여 JNI에서 메모리 부족 현상이 발생합니다.

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; 

} 

편집 : 추가/내 코드를 삭제 출시,하지만 지금은 @@@ ABORTING: INVALID HEAP ADDRESS IN dlfree:0: gralloc_module_lock: Cannot lock buffer ID=55438 before register (0x0)

답변

0

같은 오류가 난 당신이 그런 식으로 frameAddress을 사용할 수 없습니다 생각 얻을. 대신 GetByteArrayElements/ReleaseByteArrayElements를 사용하여 데이터에 대한 실제 포인터를 가져와 적절한 유형의 매트를 구성해야합니다. 예 : http://ruckus.tumblr.com/post/18055652108/writing-a-basic-image-filter-in-android-using-ndk

+0

매트를 전달하는 방법을 사용하여 http://stackoverflow.com/questions/22752820/pass-and-return-opencv-mat-object-with-jni 예제를 보았습니다. 하지만 나는 이것이 충돌의 원인이라고 생각하지는 않지만 또 다른 전달 방법을 시도 할 것입니다. –

+0

미안 해요, 항상 JNI 내부에서 Mat를 만들고 전에 getNativeObjAddr를 사용한 적이 없습니다. –