Android NDK層編譯OpenCV代碼開發詳解

2022-01-24 OpenCV學堂
Android NDK層編譯OpenCV代碼開發詳解

使用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

相關焦點

  • WSL2 編譯 Android 版本 emu-ex-plus-alpha 的 Snes9x EX+
    hl=zh-cn#command-tools解壓 -> D:\Develop\Android-SDK-Linux\tools### 2.2.2 Windows 下載 Linux Android NDKhttps://developer.android.google.cn/ndk/downloads?
  • xmake-gradle 插件 v1.0.7 發布,集成 xmake 快速構建 Android JNI...
    目前在 gradle 中做 android jni 相關集成開發,有兩種方式,通過 ndkBuild 或者 CMake 來支持,gradle 也內置了這兩工具的集成但是維護 Android.mk 還是非常繁瑣的,尤其是對於大型項目會比較痛苦,而 cmake 的 dsl 語法不夠簡潔直觀,我個人也不是很喜歡,因此我先前整了 xmake 來實現跨平臺開發,優勢就是: 簡單,快速
  • NDK系列-如何使用C/C++編寫帶EGL功能的NativeActivity
    3、開發步驟限制最低SDK版本:<uses-sdk android:minSdkVersion="9" />聲明應用只包含原生代碼,而不含 Java 代碼:<application android:hasCode="false">
  • 樹莓派3b編譯安裝完整OpenCV-3.4.1 for Python3
    具體細節請參考我在愛板論壇的另一篇帖子:樹莓派搭建基於Python3和OpenCV實現的解魔方機器人二、OpenCV-3.4.1和OpenCV_Contrib-3.4.1源文件下載這裡大家可以去官網下載,直接分享下載連結:https://github.com/opencv/opencv/archive/3.4.1.ziphttps
  • 使用visual studio或msys2(mingw64)與VS Code編譯並使用openCV
    Windows系統下OpenCV及第三方庫文件的使用與下載如果沒有特殊要求,在Windows系統下可以直接使用OpenCV的預編譯版本。在github的opencv項目release中選擇相應release版本即可。然而,由於版權原因,預編譯的opencv並沒有包含諸多第三方工具,因此,如果要使用一些第三方工具,或者要在linux系統下使用openCV的話,還需要自己從源碼進行編譯。
  • 社區分享 | 拯救 TensorFlow Lite 編譯痛點
    tensorflow/lite下的libtensorflowlite.so:bazel build --cxxopt='-std=c++11' -c opt \ --config=android_arm \ //tensorflow/lite:libtensorflowlite.so其中--config=android_arm 表示兼容 armeabi-v7a
  • Android 加快apk的構建速度,如何把編譯時間從130秒降到17秒
    class文件,輸出的路徑是app/build/intermediates/classes/debug編譯的輸入目錄有項目源碼目錄,默認路徑是app/src/main/java,可以通過sourceSets的dsl配置,允許有多個(列印project.android.sourceSets.main.java.srcDirs可以查看當前所有的源碼路徑,具體配置可以參考
  • Android Flutter 混合開發高仿大廠 App
    lib_network: 網絡庫,使用 okhttp 插件二次封裝,業務層簡單的調用即可lib_webview: 打開網頁的webview庫,使用了 agentweb 插件二次封裝,業務層只需要一句代碼即可完成網頁的跳轉lib_image_loader: 圖片加載庫,使用了 glide 插件二次封裝,業務層只需一句代碼即可加載不同參數的圖片lib_asr: 百度AI語音庫,通過 Android
  • 致初入Android開發一封信
    正如大家所知,今年android的行情令人堪憂,android從業人員也成井噴的態勢。以現在的單位來說,每天都有大批的android和ios來應聘,現在招聘網站上找實習的或者學徒的基本都是培訓機構,去到都會叫你先培訓然入職,直接去找工作吧,從低做起!現在還在自學當中,這是多麼恐慌。現在it這麼火,各種經驗簡歷編造,真的是很多人不願意看到的。
  • 從零開始的Android新項目11 - 組件化實踐(1)
    並行開發,常見於複雜的各種東西往裡塞的大型應用,比如 —— 手Q、手空、手淘、支付寶、大眾點評、攜程等等。這些團隊的 Android 開發動輒是數百人,並分成好幾個業務組,如此要並行開發便需要解耦各個模塊,避免互相依賴。
  • gcc&arm-linux-gcc編譯過程詳解
    點擊關注「百問科技」,置頂公眾號嵌入式乾貨,一鍵送達arm裸機1期加強版第9課,內容實在太多,如果編輯成一篇文章,估計大家難消化所以我把它拆分為三部分
  • Android Studio 4.1終於發布了!
    此版本的一大主題是幫助你在使用 Android Jetpack 庫(這是 Android 的庫套件,旨在幫助開發人員遵循最佳實踐並更快地編寫代碼)時提高工作效率。根據大家的反饋,我們對代碼編輯體驗以及流行 Android 庫的 IDE 集成做了許多改進。
  • 怎麼玩轉Appium圖像識別技術OpenCV,這波操作你必須GET!
    在我們做 App 自動化測試的時候,會發現很多場景下的元素沒有 id、content-desc、text 等屬性,並且有可能會碰到由於開發採用的是自定義
  • 深入探索 Android 包瘦身(上)
    4、使用 android-classshark 進行 APK 分析android-classshark項目地址(https://github.com/google/android-classyshark)android-classshark 是一個 面向 Android 開發人員的獨立二進位檢查工具
  • OpenCV人臉識別之一:數據收集和預處理
    本系列人臉識別文章用的是opencv2,最新版的opencv3.2的代碼請參考文章:《OpenCV之識別自己的臉——C++源碼放送》;《人臉識別源碼運行指南》(小編附在文末)前段時間對人臉檢測進行了一些嘗試:人臉檢測(C++/Python)(http://www.jianshu.com/p/504c081d7397)但是檢測和識別是不同的,檢測解決的問題是圖片中有沒有人臉;而識別解決的問題是
  • Android Studio 4.1重磅發布:支持內嵌安卓模擬器!
    此版本的一大主題是幫助你在使用 Android Jetpack 庫(這是 Android 的庫套件,旨在幫助開發人員遵循最佳實踐並更快地編寫代碼)時提高工作效率。根據大家的反饋,我們對代碼編輯體驗以及流行 Android 庫的 IDE 集成做了許多改進。
  • Android減包 - 減少APK大小
    res/: 包含了沒被被編譯到resources.arsc的資源。lib/: 包含了針對處理器層面的被編譯的代碼。這個目錄針對每個平臺類型都有一個子目錄,比如armeabi, armeabi-v7a, arm64-v8a, x86, x86_64和mips。
  • Unity Android Plugin開發指南
    然後通過以下代碼來訪問掛載在TGameObj對象上的腳本的OnButtonClick方法:UnityPlayer.UnitySendMessage("TGameObj", "OnButtonClick", "Greetings from Java");Unity接口設計的最佳實踐本節將介紹一個用於封裝Java代碼的通用設計方式,可以高效地將Java代碼的API
  • 教你用OpenCV人臉檢測自動給頭像戴聖誕帽(附代碼)
    本文長度為3400字,建議閱讀7分鐘跟著代碼走,教你自動給頭像帶上聖誕帽
  • 物聯網開發筆記——嵌入式開發之Linux系統中C程序的編譯與調試
    嵌入式開發學習C語言打下基礎。本節介紹《Linux系統中C程序的編譯與調試》。1 首先了解一下什麼是程序設計?1)計算機基本結構馮·諾依曼結構也稱普林斯頓結構,是一種將程序指令存儲器和數據存儲器合併在一起的存儲器結構。