2015-03-02 126 views
2

我目前正在開發一些使用OpenCv的Android API和JNI進行更快處理的東西。OpenCV Mat處理Android JNI

目前,該程序從設備相機獲取一幀,並將RGBA-Matrix轉發給JNI接口的C++算法。

這通常工作,但試圖以任何方式處理基質的時候,我得到一個SIGABRT -6錯誤與以下跟蹤:

D/JNI/LaneDetection(15547): Processing frame 
D/JNI/LaneDetection(15547): frame type: 24 
D/JNI/LaneDetection(15547): frame rows, cols: 1080, 1920 
D/JNI/LaneDetection(15547): grey_frame type: 24 
D/JNI/LaneDetection(15547): grey_frame rows, cols: 1080, 1920 
I/DEBUG ( 242):  #00 pc 00036d58 /system/lib/libc.so (tgkill+12) 
I/DEBUG ( 242):  #01 pc 00014231 /system/lib/libc.so (pthread_kill+52) 
I/DEBUG ( 242):  #02 pc 00014f93 /system/lib/libc.so (raise+10) 
I/DEBUG ( 242):  #03 pc 000116a5 /system/lib/libc.so (__libc_android_abort+36) 
I/DEBUG ( 242):  #04 pc 0000fd3c /system/lib/libc.so (abort+4) 
I/DEBUG ( 242):  #05 pc 00724ce4 /data/app/at.sapps.sdo-2/lib/arm/libopencv_java.so (__gnu_cxx::__verbose_terminate_handler()+276) 
I/DEBUG ( 242):  #06 pc 007220e8 /data/app/at.sapps.sdo-2/lib/arm/libopencv_java.so (__cxxabiv1::__terminate(void (*)())+8) 
I/DEBUG ( 242):  #07 pc 0072212c /data/app/at.sapps.sdo-2/lib/arm/libopencv_java.so (std::terminate()+20) 
I/DEBUG ( 242):  #08 pc 007222b4 /data/app/at.sapps.sdo-2/lib/arm/libopencv_java.so (__cxa_throw+148) 
I/DEBUG ( 242):  #09 pc 001a5a41 /data/app/at.sapps.sdo-2/lib/arm/libopencv_java.so (cv::error(cv::Exception const&)+80) 
I/DEBUG ( 242):  #10 pc 00267243 /data/app/at.sapps.sdo-2/lib/arm/libopencv_java.so (cv::cvarrToMat(void const*, bool, bool, int)+134) 
I/DEBUG ( 242):  #11 pc 0035bcbb /data/app/at.sapps.sdo-2/lib/arm/libopencv_java.so (cvCvtColor+22) 
I/DEBUG ( 242):  #12 pc 00006195 /data/app/at.sapps.sdo-2/lib/arm/liblane_tracker_module.so (onFrame(cv::Mat*)+252) 

相應的C++調用它導致錯誤如下:

cvCvtColor(frame, grey, CV_RGBA2GRAY); // convert to grayscale 

正如您可能已經注意到的,矩陣類型和尺寸是相同的。我也試過CV_BGRA2GRAY,結果相同。 (不過,我敢肯定這是一個RGBA矩陣,因爲JAVAAPI呼叫inputframe.rgba()來獲得矩陣..)

的墊灰色被初始化與以下電話:

Mat *grey = new Mat(frame_size, 24); // global, 24=type= same as original frame Mat 
    // method init: 
    video_size.height = frame->rows; 
    video_size.width = frame->cols; 
    frame_size = cvSize(video_size.width, video_size.height); 
    grey = new cv::Mat(frame_size, 24, 3); 

我無法弄清楚實際問題是什麼,也許是由於我缺乏C++技能。

我很感謝每一個幫助&謝謝你提前。

java代碼簡而言之:

@Override 
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) { 
rgbaMat = inputFrame.rgba(); 
nativeDetect(rgbaMat.getNativeObjAddr(), lanes.getNativeObjAddr()); 
return rgbaMat; 
} 


private static native void nativeDetect(long inputImage, long lanes); 

解答:用c方法是所有罪惡的根源。改變他們到他們的C++等價物解決了這個問題

+0

我加了java代碼。 當前的構造函數是Mat * gray = new Mat(frame_size,24);哪個也行不通(我願意提供建議)。 類型「24」源自原始框架Mat,相機API將移交。這就是爲什麼我採取相同的,因爲如果你採取不同類型的矩陣,我會看到有compability問題。 – Aeefire 2015-03-02 15:03:23

回答

2

對不起,但這個C++代碼,讓我感到困惑。什麼類型是24或3的構造函數...我認爲,你應該使用OpenCV常量來定義類型。此外,您使用的是C函數,而不是使用C++函數

總之,方法cv::cvtColor應分配必要的內存,而你只需要做到:

Mat grey; 
cv::cvtColor(frame, grey, CV_RGBA2GRAY); 

最後,我會克隆你的輸入幀(frame),以避免與你的Android代碼的內存問題:

cv::Mat newMat = frame.clone() 

doc搜索查找C++函數..

+0

我編輯過的東西+添加了對問題的評論。 – Aeefire 2015-03-02 15:04:57

+0

上面的代碼沒有工作。 frame.clone()的確切原因是什麼?如何複製一個框架解決內存問題?你的意思是關於併發嗎? – Aeefire 2015-03-02 15:13:11

+0

OpenCV的Android SDK將分配內存範圍內的每個幀,並且可能會覆蓋正在處理的幀......如何創建Mat幀?還有哪個錯誤引發我的回答? – 2015-03-02 15:19:43

0

我找不到像定義「灰色」時使用的任何構造函數。你可以用下面的方法改變它。

grey = new cv::Mat(frame_size, CV_8UC1); 

我希望它有幫助。

+0

使用的構造函數是: \t gray = new cv :: Mat(frame_size,24,3); 因爲「24」是frame-rgba-matrix類型,您可以在跟蹤中看到 儘管如此,我也會嘗試您的解決方案。 編輯:相同的錯誤,然而類型的「灰色」現在是0(而原始幀是類型24) – Aeefire 2015-03-02 14:13:31

+0

我想灰色圖像應該是1通道,如果你只是定義你的目標圖像像「墊灰色;」 ,cvtColor函數應該處理[書籍]中提到的矩陣的初始化參數(https://books.google.com.tr/books?id=UjWoIFHcr58C&pg=PT105&lpg=PT105&dq=CV_BGRA2GRAY&source=bl&ots=S9e4Brrt-x&sig=XZZzW8pDBFrn5H3KOo1wT66RqKk&hl= tr&sa = X&ei = e3f0VOC9FcmWarWMgNAK&ved = 0CC8Q6AEwAzgK#v = onepage&q = CV_BGRA2GRAY&f = false) – alitemel 2015-03-02 14:52:50

+0

您的意思是:「Mat * gray = new Mat();」 ?或者只是「墊*灰色;」顏色轉換的「目標圖像」是矩陣「灰色」 – Aeefire 2015-03-02 14:55:35