使用Android NDK開發編譯OpenCV C++代碼,這個在OpenCV4Android開發中會經常遇到的要求,因為OpenCV4Android SDK多數Java代碼都是基於JNI調用,如果對於實時性與應用要求比較高的場合來說,多次頻繁調用JNI層本身就會導致很大的資源開銷,這個時候就需要將全部的處理封裝在C++層,在C++中調用OpenCV相關API函數,同時通過在JNI層面定義本地方法,力爭做到每次處理圖像,只調用JNI一次,這樣就會達到比較高的運行速度與好的用戶體驗。下面我們就從OpenCV4Android SDK與Android NDK開發環境搭建,OpenCV C++程序實現,編譯完成與運行各個環節介紹如何在Android NDK層面編譯OpenCV C++代碼實現JNI調用。
一:環境搭建首先下載Android Studio與Android SDK,在Android Studio中創建一個新項目,然後參照【OpenCV學堂】之前的文章《OpenCv3.2集成Android Studio開發配置》完成OpenCV4Android開發環境搭建即可。
二:JNI接口定義在MainActivity中添加一個native本地方法即可
public native void convertGray(long srcAddress, long dstAddress);
三:OpenCV C++代碼實現然後在app/src下面新建一個目錄jni,然後創建一個cpp源文件,把下面的代碼copy到其中保存
#include<jni.h>
#include<opencv2/opencv.hpp>
#include <iostream>
#include<vector>
#include <android/log.h>
#define LOG_TAG "MYOPENCV_TEST"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
using namespace cv;
using namespace std;
extern"C" {
JNIEXPORT void JNICALL Java_com_example_zhigang_myapplication_MainActivity_convertGray(JNIEnv* env, jobject, jlong srcAddress, jlong dstAddress)
{
Mat& src = *(Mat*)srcAddress;
Mat& dst = *(Mat*)dstAddress;
cvtColor(src, dst, COLOR_BGR2GRAY);
LOGD( "Method Description: %s", "convert to gray image..." );
}
}
其中com.example.zhigang.myapplication.MainActivity表示當前MainActivity完整的包路徑。定義的JNI方法為convertGray,兩個參數分別是源圖像的地址與輸出的灰度圖像的地址,實現的功能是把彩色圖像轉換為灰度圖像。
四:編譯運行上述代碼要想完整的編譯與運行,需要創建兩個文件Android.mk與Application.mk文件,然後把下面的內容copy到Android.mk中去:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
include D:/opencv-3.3/opencv/android/install/sdk/native/jni/OpenCV.mk
LOCAL_MODULE := gray_converter
LOCAL_SRC_FILES := gray_mat.cpp
LOCAL_LDLIBS += -llog -ldl
include $(BUILD_SHARED_LIBRARY)
其中include的路徑是你OpenCV4Android SDK實際所在的路徑,然後把下面內容copy到Application.mk中去:
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi-v7a
APP_PLATFORM := android-14
然後對當前項目添加NDK支持,打開cmd,切換到src/jni目錄,然後運行下面的命令行: /ndk-build 即可完成編譯,生成的so文件copy到app/libs中去即可,然後就可以在MainActivity的onCreate方法中通過如下代碼加載庫文件, System.loadLibrary("gray_converter"); 然後就可以參考上面提到文章調用完成代碼演示即可。代碼如下:
private void convertGray() {
Mat src = new Mat();
Mat temp = new Mat();
Mat dst = new Mat();
Bitmap image = BitmapFactory.decodeResource(this.getResources(), R.drawable.lena);
Utils.bitmapToMat(image, src);
Imgproc.cvtColor(src, temp, Imgproc.COLOR_RGBA2BGR);
Log.i("CV", "image type:" + (temp.type() == CvType.CV_8UC3));
//Imgproc.cvtColor(temp, dst, Imgproc.COLOR_BGR2GRAY);
convertGray(temp.getNativeObjAddr(), dst.getNativeObjAddr());
Utils.matToBitmap(dst, image);
ImageView imageView = (ImageView)findViewById(R.id.image_lena);
imageView.setImageBitmap(image);
// release memory
src.release();
temp.release();
dst.release();
}
最終運行結果:
學而不化,非學也
關注【OpenCV學堂】
長按或者掃碼下面二維碼即可關注
+OpenCV學習群 376281510
進群暗號:OpenCV