日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OpenCV向JNI层的参数转换

發布時間:2023/12/31 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenCV向JNI层的参数转换 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

??????? 九層之臺,起于累土;千里之堤毀于蟻穴;成者半于九十。最近工程項目完全可以調試,卻最后在 OpenCV向JNI層的參數轉換?這個節點上遇到麻煩,看來得好好的思考一番,仔細尋找其中的紕漏。


一、實例

????????根據可運行的openCv sample,可以用與人臉檢測的函數是這樣的:

//貌似 必須要特殊編寫,便可以默認調用!wishchin! public Mat onCameraFrame(CvCameraViewFrame inputFrame) {mRgba = inputFrame.rgba();mGray = inputFrame.gray();if (mAbsoluteFaceSize == 0) {int height = mGray.rows();if (Math.round(height * mRelativeFaceSize) > 0) {mAbsoluteFaceSize = Math.round(height * mRelativeFaceSize);}mNativeDetector.setMinFaceSize(mAbsoluteFaceSize);}MatOfRect faces = new MatOfRect();if (mDetectorType == JAVA_DETECTOR) {if (mJavaDetector != null)mJavaDetector.detectMultiScale(mGray, faces, 1.1, 2, 2, // TODO: objdetect.CV_HAAR_SCALE_IMAGEnew Size(mAbsoluteFaceSize, mAbsoluteFaceSize), new Size());}else if (mDetectorType == NATIVE_DETECTOR) {if (mNativeDetector != null)mNativeDetector.detect(mGray, faces);//Detect 面部的代碼,使用C++!wishchin!}else {Log.e(TAG, "Detection method is not selected!");}//0.2.把檢測到的框畫在圖片上!wishchin!Rect[] facesArray = faces.toArray();for (int i = 0; i < facesArray.length; i++){Core.rectangle(mRgba, facesArray[i].tl(), facesArray[i].br(), FACE_RECT_COLOR, 3); }if (mNativeDetector != null){//Detect 使用C++!wishchin!//mCamParam.dof6CamRecog(mGray,mCamParam);//具體函數已經轉移!}return mRgba; }
函數分析:

主要處理過程:

mNativeDetector.detect(mGray, faces);//Detect 面部的代碼,使用C++!wishchin!所使用的函數:

public void detect(Mat imageGray, MatOfRect faces) {nativeDetect( mNativeObj, imageGray.getNativeObjAddr(), faces.getNativeObjAddr() );}所調用的Native函數:

private static native void nativeDetect(long thiz, long inputImage, long faces);

對應CPP內的JNI接口:

JNIEXPORT void JNICALL Java_com_example_feeljulygpsmap_FeelJulyGpsMap_nativeDetect (JNIEnv * jenv, jclass,jlong thiz,jlong imageGray, jlong faces) {LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect enter");try{vector<Rect> RectFaces;((DetectionBasedTracker*)thiz)->process(*((Mat*)imageGray));((DetectionBasedTracker*)thiz)->getObjects(RectFaces);vector_Rect_to_Mat(RectFaces, *((Mat*)faces));}catch(cv::Exception& e){LOGD("nativeCreateObject caught cv::Exception: %s", e.what());jclass je = jenv->FindClass("org/opencv/core/CvException");if(!je)je = jenv->FindClass("java/lang/Exception");jenv->ThrowNew(je, e.what());}catch (...){LOGD("nativeDetect caught unknown exception");jclass je = jenv->FindClass("java/lang/Exception");jenv->ThrowNew(je, "Unknown exception in JNI code DetectionBasedTracker.nativeDetect()");}LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect exit"); }


二、參數解析

1.java到C++

第一層參數轉換:由Java到C++,通過jlong類型

??????? 轉換語法:

nativeDetect( mNativeObj, imageGray.getNativeObjAddr(), faces.getNativeObjAddr() );通過Mat型 .getNativeObjAddr()成員函數獲取矩陣地址,通過jlong型進行JNI參數代入

對應形式:

JNIEXPORT void JNICALL Java_com_example_feeljulygpsmap_FeelJulyGpsMap_nativeDetect (JNIEnv * jenv, jclass,jlong thiz,jlong imageGray, jlong faces)函數進行運算的過程:

((DetectionBasedTracker*)thiz)->process(*((Mat*) imageGray) );

涉及到的第二次參數轉化:

*((Mat*) imageGray) 把jlong型在C++層強制轉化為Mat類型的指針,供其他C++函數使用,由此完成Java層到C++層的全部語法轉換!


其中前兩個參數的作為JNI本地參數默認調用;

第三個參數jlong?thiz顧名思義即是所使用參數類的載入地址,通過獲取C++類的地址載入,由此可以使用在底層使用C++的類,并獲取C++類的類函數和成員變量。

第四個和第五個參數分別對應了java層載入的兩個mat型參數的地址,由此完成java向JNI層的陷入。

自此檢測,我的代碼和sample在語法層面完全一致,并且代入變元的語義一致,在此過程的移植方法上,理所應當是沒有錯誤的。


注意事項:不管有沒有聲明const,載入的Mat型是不能被改變的,已經初始化的mat型不能再被修改,比如

<del>*((Mat*) imageGray)</del> 為什么?難道是為了保持上層變量的完整性?


2.由C++到java層

參數變元,經過一系列運算,得到函數結果,或者以參數或者以返回值的方式向java層返回。

由C++到java層返回的語法是這樣的:

mNativeDetector.detect(mGray, faces);//Detect 面部的代碼,使用C++!wishchin!
所調用的java函數:

mNativeDetector.detect(mGray, faces);//Detect 面部的代碼,使用C++!wishchin! <pre name="code" class="java"> public void detect(Mat imageGray, MatOfRect faces) {nativeDetect( mNativeObj, imageGray.getNativeObjAddr(), faces.getNativeObjAddr() );}

所使用的Native函數:

private static native void nativeDetect(long thiz, long inputImage, long faces);

對應CPP內的JNI接口:

JNIEXPORT void JNICALL Java_com_example_feeljulygpsmap_FeelJulyGpsMap_nativeDetect (JNIEnv * jenv, jclass,jlong thiz,jlong imageGray, jlong faces);JNI函數處理過程:

((DetectionBasedTracker*)thiz)->getObjects(RectFaces);vector_Rect_to_Mat(RectFaces, *((Mat*)faces));參數轉變的函數調用:

vector_Rect_to_Mat(RectFaces, *((Mat*)faces));參數轉變函數:

inline void vector_Rect_to_Mat(vector<Rect>& v_rect, Mat& mat) {mat = Mat(v_rect, true); }

完成效果:

返回臉部檢測的識別框,壓入Vector,并通過函數強制轉換成 Mat型指針,

java頂層調用:

//0.2.把檢測到的框畫在圖片上!wishchin!Rect[] facesArray = faces.toArray();這樣可以通過數組轉化為java層的 CvArray 類型,

以便

for (int i = 0; i < facesArray.length; i++){Core.rectangle(mRgba, facesArray[i].tl(), facesArray[i].br(), FACE_RECT_COLOR, 3); }
此代碼段使用。

顯示效果為:




總結

以上是生活随笔為你收集整理的OpenCV向JNI层的参数转换的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。