前言
眾所周知??, OpenCV 4.9.0 罕見的在 Android 平臺上做出調(diào)整,具體更新內(nèi)容請移步難得一見的 Android OpenCV ChangeLog。然而,近期筆者在查閱 OpenCV Github Wiki 時,又發(fā)現(xiàn)了新東西??,一篇名為 "Custom OpenCV Android SDK and AAR package build"的 Wiki。以前我們編譯 SDK 采用的是CMake方式,具體可參考全網(wǎng)首發(fā)微信二維碼引擎Android平臺移植,而本篇新 Wiki 起草于 2023年11月23日,內(nèi)容比較新,但是整體還是基于 CMake,只是采用 python 封裝腳本方便執(zhí)行而已,以前應(yīng)該也可以采用這種方式執(zhí)行,只是官方一直未正式發(fā)布指南。本文主要記錄實踐過。
環(huán)境準(zhǔn)備
- Ubuntu 20.04+(筆者版本
Ubuntu 20.04.6 LTS
) - Android Studio(筆者未使用)
- OpenJDK 17
- CMake
- Ninja build tool
- OpenCV source code (https://github.com/opencv/opencv)
- (Optional) OpenCV contrib modules source code (https://github.com/opencv/opencv_contrib)
- (Optional) OpenCV test data (https://github.com/opencv/opencv_extra)
步驟
1. 安裝環(huán)境
-
安裝 OpenJDK 17
sudo apt install openjdk-17-jdk openjdk-17-jre
-
安裝 CMake
sudo apt install cmake
-
安裝 Ninja build tool
sudo apt install ninja-build
-
安裝 build-tools、sdk和 ndk
Install SDK 21.1.2 and NDK 18.1 using SDK manager in Android Studio (use checkbox “Show package details” to choose a version)
文中的
21.1.2
應(yīng)該指代的是build-tools
,因為 Android API級別向來都是大版本,ndk 版本則是18.1.5063045
,sdk 由于文中暫未明確指出,所以我們采用的是Android 21
。sdkmanager "platforms;android-21" sdkmanager --install "ndk;18.1.5063045" sdkmanager --install "build-tools;21.1.2"
-
安裝 python3
若 Ubuntu 系統(tǒng)默認(rèn)未安裝,需手動安裝
sudo apt install python3
。
2. 下載源碼
-
下載 opencv 源碼
git clone https://github.com/opencv/opencv.git
-
(可選)下載 opencv_contrib 源碼
git clone https://github.com/opencv/opencv_contrib.git
-
(???)下載 opencv_extra 源碼
未發(fā)現(xiàn)使用的地方,暫時先不下載
筆者將二個源碼文件夾放在同一層級目錄,方便后續(xù)配置變量。
3. 配置編譯目錄和環(huán)境變量
-
新建
build
目錄筆者此處在二個源碼文件夾同一層級目錄下創(chuàng)建
build
文件夾 -
配置環(huán)境變量
筆者修改
.bashrc
文件,并在文檔末尾追加如下內(nèi)容export YOUR_OPENCV_SRC_FOLDER=/home/yi/opencv # opencv 源碼路徑 export YOUR_CONTRIB_SRC_FOLDER=/home/yi/opencv_contrib # opencv_contrib 源碼路徑 export YOUR_OPENCV_BUILD_FOLDER=/home/yi/build # 構(gòu)建目錄 export ANDROID_SDK=/home/yi/sdk # Android SDK目錄 export ANDROID_NDK_HOME=/home/yi/sdk/ndk/18.1.5063045 # ndk目錄
4. 編譯 SDK
python3 $YOUR_OPENCV_SRC_FOLDER/platforms/android/build_sdk.py $YOUR_OPENCV_BUILD_FOLDER $YOUR_OPENCV_SRC_FOLDER --ndk_path $ANDROID_NDK_HOME --sdk_path $ANDROID_SDK --extra_modules_path $YOUR_CONTRIB_SRC_FOLDER/modules --config $YOUR_OPENCV_SRC_FOLDER/platforms/android/ndk-18-api-level-21.config.py
配置 ANDROID_PROJECTS_BUILD_TYPE="GRADLE"
,可編譯生成libopencv_java.so
與對應(yīng)的 Java Wrapper 文件。由于使用的是 ndk-18-api-level-21.config.py
配置文件,會生成 armeabi-v7a、arm64-v8a、x86_64、x86
四種架構(gòu)的二進制共享庫文件。
ABIs = [
ABI("2", "armeabi-v7a", None, 21, cmake_vars=dict(ANDROID_ABI='armeabi-v7a with NEON')),
ABI("3", "arm64-v8a", None, 21),
ABI("5", "x86_64", None, 21),
ABI("4", "x86", None, 21),
]
如果只需要部分架構(gòu)的 so 文件,調(diào)整文件留下對應(yīng)的ABI變量即可。
cmake_vars
參數(shù)用來傳遞自定義 CMake 編譯參數(shù)。例如:
- arm64-v8a架構(gòu)下不編譯 G-API 和 DNN 模塊
ABI("3", "arm64-v8a", None, 21, cmake_vars=dict('BUILD_opencv_gapi': 'OFF', 'BUILD_opencv_dnn': 'OFF'))
- 指定 OpenCV 部分構(gòu)建工具的版本
ABI("3", "arm64-v8a", None, 21, cmake_vars=dict('ANDROID_GRADLE_PLUGIN_VERSION': '7.3.1', 'GRADLE_VERSION': '7.5.1', 'KOTLIN_PLUGIN_VERSION': '1.5.20'))
- 指定 CMake find_package 過程的外部庫位置
ABI("3", "arm64-v8a", None, 21, cmake_vars=dict('libavif_DIR': '<path to libavif library cross-compiled for Android arm-v8a>')
所以剛才我們提到的 BUILD_ANDROID_PROJECTS="OFF"
或者 ANDROID_PROJECTS_BUILD_TYPE="GRADLE"
均可以在這里配置。
比如,我們將 ndk-18-api-level-21.config.py
調(diào)整為
ABIs = [
ABI("2", "armeabi-v7a", None, 21, cmake_vars=dict(ANDROID_ABI='armeabi-v7a with NEON', ANDROID_PROJECTS_BUILD_TYPE='GRADLE'))
]
則只會生成 armeabi-v7a
架構(gòu)的 so 文件。
5. 編譯 AAR
python3 $YOUR_OPENCV_SRC_FOLDER/platforms/android/build_java_shared_aar.py $YOUR_OPENCV_BUILD_FOLDER/OpenCV-android-sdk
6. 腳本參數(shù)與編譯參數(shù)
以build_sdk.py
舉例如何查找腳本參數(shù)與編譯參數(shù),雖然腳本參數(shù)最后都會落腳到編譯參數(shù)。
-
build_sdk.py
腳本參數(shù)
parser = argparse.ArgumentParser(description='Build OpenCV for Android SDK')
parser.add_argument("work_dir", nargs='?', default='.', help="Working directory (and output)")
parser.add_argument("opencv_dir", nargs='?', default=os.path.join(SCRIPT_DIR, '../..'), help="Path to OpenCV source dir")
parser.add_argument('--config', default='ndk-18-api-level-21.config.py', type=str, help="Package build configuration", )
parser.add_argument('--ndk_path', help="Path to Android NDK to use for build")
parser.add_argument('--sdk_path', help="Path to Android SDK to use for build")
parser.add_argument('--use_android_buildtools', action="store_true", help='Use cmake/ninja build tools from Android SDK')
parser.add_argument("--modules_list", help="List of modules to include for build")
parser.add_argument("--extra_modules_path", help="Path to extra modules to use for build")
parser.add_argument('--sign_with', help="Certificate to sign the Manager apk")
parser.add_argument('--build_doc', action="store_true", help="Build javadoc")
parser.add_argument('--no_ccache', action="store_true", help="Do not use ccache during library build")
parser.add_argument('--force_copy', action="store_true", help="Do not use file move during library build (useful for debug)")
parser.add_argument('--force_opencv_toolchain', action="store_true", help="Do not use toolchain from Android NDK")
parser.add_argument('--debug', action="store_true", help="Build 'Debug' binaries (CMAKE_BUILD_TYPE=Debug)")
parser.add_argument('--debug_info', action="store_true", help="Build with debug information (useful for Release mode: BUILD_WITH_DEBUG_INFO=ON)")
parser.add_argument('--no_samples_build', action="store_true", help="Do not build samples (speeds up build)")
parser.add_argument('--opencl', action="store_true", help="Enable OpenCL support")
parser.add_argument('--no_kotlin', action="store_true", help="Disable Kotlin extensions")
parser.add_argument('--shared', action="store_true", help="Build shared libraries")
parser.add_argument('--no_media_ndk', action="store_true", help="Do not link Media NDK (required for video I/O support)")
args = parser.parse_args()
- CMake 編譯參數(shù)
cmake_vars = dict(
CMAKE_TOOLCHAIN_FILE=self.get_toolchain_file(),
INSTALL_CREATE_DISTRIB="ON",
WITH_OPENCL="OFF",
BUILD_KOTLIN_EXTENSIONS="ON",
WITH_IPP=("ON" if abi.haveIPP() else "OFF"),
WITH_TBB="ON",
BUILD_EXAMPLES="OFF",
BUILD_TESTS="OFF",
BUILD_PERF_TESTS="OFF",
BUILD_DOCS="OFF",
BUILD_ANDROID_EXAMPLES=("OFF" if self.no_samples_build else "ON"),
INSTALL_ANDROID_EXAMPLES=("OFF" if self.no_samples_build else "ON"),
# BUILD_ANDROID_PROJECTS="OFF",
# ANDROID_PROJECTS_BUILD_TYPE="GRADLE"
)
查找并理解編譯參數(shù),配合實踐,應(yīng)該可以編譯出你想要的文件。
FAQ
?????Android SDK: Can’t build Android projects as requested by BUILD_ANDROID_PROJECTS=ON variable.
?**解決辦法:**配置 BUILD_ANDROID_PROJECTS=”O(jiān)FF“
或者 ANDROID_PROJECTS_BUILD_TYPE="GRADLE" # 或者 ”ANT“
。作為 Android 開發(fā)自然是配置 Gradle 嘛,不然顏面何在,當(dāng)然我們也可以在 config 文件中配置。
?????MainActivity.java:57: 錯誤: 找不到符號
mModelBuffer = loadFileFromResource(R.raw.mobilenet_iter_73000);
^
符號: 變量 raw
位置: 類 R
/home/yi/opencv/samples/android/mobilenet-objdetect/src/org/opencv/samples/opencv_mobilenet/MainActivity.java:58: 錯誤: 找不到符號
mConfigBuffer = loadFileFromResource(R.raw.deploy);
^
符號: 變量 raw
位置: 類 R
?**解決辦法:**從官方 SDK 文件中手動復(fù)制。
?????gradle-7.6.3-all.zip 下載失敗文章來源:http://www.zghlxwxcb.cn/news/detail-812355.html
?**解決辦法:**下載離線版本存放至 .gradle 對應(yīng)目錄下即可。文章來源地址http://www.zghlxwxcb.cn/news/detail-812355.html
到了這里,關(guān)于Android OpenCV(七十七):官方指南方式編譯 OpenCV Android SDK.md的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!