OpenCV 4.10.0 移植 - Android
前文:
Ubuntu 编译 OpenCV SDK for Android + Linux
OpenCV 4.10.0 移植
概述
在移动应用开发领域,Android平台与OpenCV库的结合为开发者提供了强大的图像处理和计算机视觉能力。OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库,而Android则是全球最流行的移动操作系统之一。两者的结合使得开发者能够在移动设备上实现复杂的图像处理功能,从简单的滤镜应用到高级的物体识别和增强现实体验。
Android平台为OpenCV提供了广泛的硬件支持和用户基础,而OpenCV则为Android开发者提供了丰富的图像处理算法和工具。这种协同关系使得开发者能够轻松地将计算机视觉技术集成到移动应用中,无需从零开始实现复杂的图像处理算法。无论是人脸检测、二维码识别、图像增强还是实时视频处理,Android与OpenCV的结合都为这些功能提供了可靠的技术基础。
随着移动设备计算能力的不断提升,Android+OpenCV的组合正在推动移动端计算机视觉应用的快速发展,为医疗、安防、零售、娱乐等多个行业带来了创新的解决方案.
针对Ubuntu 编译 OpenCV SDK for Android + Linux一文:
- 弥补缺少java文件输出
- 使用Gradle
- 增加示例测试
环境
属性 | 值 |
---|---|
OpenJDK | 11 |
abi | armeabi-v7a |
Android Gradle Plugin Version | 4.2.2 |
Gradle Version | 6.7.1 |
cmake | 3.16.3 |
NDK | 22.0.7026061 |
编译脚本:
注: OpenCV的下载解压, 前文已有, 不在赘述.
构建的方法有两种:
- 使用python脚本
- 使用传统的make
export ANDROID_HOME=/home/xxxxx/Android/Sdk/
export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools
export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/22.0.7026061
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
TOOLCHAINS=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmakewithPython=0output_dir=build-android
if [ ! -d $output_dir ]; thenmkdir $output_dir
fifor arg in $@; doif [ $arg == "clean" ]; thenecho "build with clean"rm -rf $output_dir/*elif [ $arg == "python" ]; thenecho "build via python"withPython=1;fidone## -------------------- ##
cd $output_direcho "START Configure..."
echo "build via python is $withPython"## OK
if [ $withPython == "1" ]; thenpython ../platforms/android/build_sdk.py \--config=../platforms/android/ndk-22.config.py \--ndk_path=$ANDROID_NDK_HOME \--sdk_path=$ANDROID_HOME \--no_ccache \--no_samples_build \. \..
elseabis="armeabi-v7a arm64-v8a"for abi in $abis; doecho "build ABI:$abi"cmake \-D ANDROID_SDK=$ANDROID_HOME \-D ANDROID_NDK=$ANDROID_NDK_HOME \-D CMAKE_ANDROID_NDK=$ANDROID_NDK_HOME \-D CMAKE_TOOLCHAIN_FILE=$TOOLCHAINS \-D ANDROID_TOOLCHAIN='clang' \-D ANDROID_ABI=$abi \-D ANDROID_STL='c++_shared' \-D ANDROID_PLATFORM_ID='2' \-D ANDROID_GRADLE_PLUGIN_VERSION='4.1.2' \-D GRADLE_VERSION='6.5' \-D KOTLIN_PLUGIN_VERSION='1.5.10' \-D BUILD_ANDROID_EXAMPLES='OFF' \-D INSTALL_ANDROID_EXAMPLES='OFF' \-D BUILD_DOCS='OFF' \-D WITH_OPENCL='OFF' \-D WITH_CUDA=OFF \-D WITH_MATLAB=OFF \-D BUILD_EXAMPLES=OFF \-D BUILD_PERF_TESTS=OFF \-D BUILD_TESTS=OFF \-D WITH_TBB='OFF' \-D INSTALL_TESTS='OFF' \-D INSTALL_CREATE_DISTRIB='OFF' \-D BUILD_KOTLIN_EXTENSIONS='OFF' \..#ninja opencv_modulesmake -j12make installdone
fiecho "--END--"## reference
# OpenJDK 11
# -D BUILD_ANDROID_PROJECTS=ON : 才能编译出JAVA# -D BUILD_SHARED_LIBS=ON 编译出so库# CMake Error at /usr/share/cmake-3.22/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
# Could NOT find OpenCV (missing: opencv_java) (found version "4.10.0")
# Call Stack (most recent call first):
# /usr/share/cmake-3.22/Modules/FindPackageHandleStandardArgs.cmake:594 (_FPHSA_FAILURE_MESSAGE)
# /media/xxxxx/codes/opencv-4.10.0/build-android/OpenCVConfig.cmake:367 (find_package_handle_standard_args)
# CMakeLists.txt:15 (find_package)# 好戏上演:为Android项目编译OpenCV 4.1.0,可按需编译模块,大大减少空间。
# https://juejin.cn/post/7225511164125610021# https://zj-image-processing.readthedocs.io/zh-cn/latest/opencv/install-configure/[OpenCV_Contrib-4.0.1]%E7%BC%96%E8%AF%91OpenCV4Android/
编译输出:
opencv-4.10.0/build-android/install/sdk$ ll
total 40
drwxrwxr-x 8 xxxxx xxxxx 4096 7月 8 15:32 ./
drwxrwxr-x 4 xxxxx xxxxx 4096 7月 8 13:47 ../
drwxrwxr-x 7 xxxxx xxxxx 4096 7月 8 15:32 build/
-rw-r--r-- 1 xxxxx xxxxx 5628 7月 8 15:27 build.gradle
drwxrwxr-x 3 xxxxx xxxxx 4096 7月 8 15:32 .cxx/
drwxrwxr-x 5 xxxxx xxxxx 4096 7月 8 13:47 etc/
drwxrwxr-x 4 xxxxx xxxxx 4096 7月 8 14:58 java/
drwxrwxr-x 2 xxxxx xxxxx 4096 7月 8 14:58 libcxx_helper/
drwxrwxr-x 6 xxxxx xxxxx 4096 7月 8 13:47 native/
导入到AndroidStudio
- settings.gradle 增加OpenCV模块
include ':opencv-4.10'
project(':opencv-4.10').projectDir = new File("opencv-4.10.0/build-android/install/sdk")
- app模块增加依赖
build.gradle
apply plugin: 'com.android.application'
android {defaultConfig {//省略app信息externalNativeBuild{ndk{abiFilters 'armeabi-v7a'}}}
}
dependencies {implementation project(':opencv-4.10')
}
- 导入OpenCV出错, 参照下文注释部分配置:
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.//
// Notes about integration OpenCV into existed Android Studio application project are below (application 'app' module should exist).
//
// This file is located in <OpenCV-android-sdk>/sdk directory (near 'etc', 'java', 'native' subdirectories)
//
// Add module into Android Studio application project:
//
// - Android Studio way:
// (will copy almost all OpenCV Android SDK into your project, ~200Mb)
//
// Import module: Menu -> "File" -> "New" -> "Module" -> "Import Gradle project":
// Source directory: select this "sdk" directory
// Module name: ":opencv"
//
// - or attach library module from OpenCV Android SDK
// (without copying into application project directory, allow to share the same module between projects)
//
// Edit "settings.gradle" and add these lines:
//
// def opencvsdk='<path_to_opencv_android_sdk_rootdir>'
// // You can put declaration above into gradle.properties file instead (including file in HOME directory),
// // but without 'def' and apostrophe symbols ('): opencvsdk=<path_to_opencv_android_sdk_rootdir>
// include ':opencv'
// project(':opencv').projectDir = new File(opencvsdk + '/sdk')
//
//
//
// Add dependency into application module:
//
// - Android Studio way:
// "Open Module Settings" (F4) -> "Dependencies" tab
//
// - or add "project(':opencv')" dependency into app/build.gradle:
//
// dependencies {
// implementation fileTree(dir: 'libs', include: ['*.jar'])
// ...
// implementation project(':opencv')
// }
//
//
//
// Load OpenCV native library before using:
//
// - avoid using of "OpenCVLoader.initAsync()" approach - it is deprecated
// It may load library with different version (from OpenCV Android Manager, which is installed separatelly on device)
//
// - use "System.loadLibrary("opencv_java4")" or "OpenCVLoader.initDebug()"
// TODO: Add accurate API to load OpenCV native library
//
//
//
// Native C++ support (necessary to use OpenCV in native code of application only):
//
// - Use find_package() in app/CMakeLists.txt:
//
// find_package(OpenCV 4.10 REQUIRED java)
// ...
// target_link_libraries(native-lib ${OpenCV_LIBRARIES})
//
// - Add "OpenCV_DIR" and enable C++ exceptions/RTTI support via app/build.gradle
// Documentation about CMake options: https://developer.android.com/ndk/guides/cmake.html
//
// defaultConfig {
// ...
// externalNativeBuild {
// cmake {
// cppFlags "-std=c++11 -frtti -fexceptions"
// arguments "-DOpenCV_DIR=" + opencvsdk + "/sdk/native/jni" // , "-DANDROID_ARM_NEON=TRUE"
// }
// }
// }
//
// - (optional) Limit/filter ABIs to build ('android' scope of 'app/build.gradle'):
// Useful information: https://developer.android.com/studio/build/gradle-tips.html (Configure separate APKs per ABI)
//
// splits {
// abi {
// enable true
// universalApk false
// reset()
// include 'armeabi-v7a' // , 'x86', 'x86_64', 'arm64-v8a'
// }
// }
//plugins {id 'com.android.library' // or 'com.android.application' if this is an app module
}//apply plugin: 'maven-publish'def openCVersionName = "4.10.0"
def openCVersionCode = ((4 * 100 + 10) * 100 + 0) * 10 + 0println "OpenCV: " +openCVersionName + " " + project.buildscript.sourceFileandroid {compileSdkVersion 31defaultConfig {minSdkVersion 21targetSdkVersion 31versionCode openCVersionCodeversionName openCVersionNameexternalNativeBuild {cmake {arguments "-DANDROID_STL=c++_shared"targets "opencv_jni_shared"}}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}buildTypes {debug {packagingOptions {doNotStrip '**/*.so' // controlled by OpenCV CMake scripts}}release {packagingOptions {doNotStrip '**/*.so' // controlled by OpenCV CMake scripts}minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'}}//buildFeatures {// prefabPublishing true// buildConfig true//}//prefab {// opencv_jni_shared {// headers "native/jni/include"// }//}sourceSets {main {jniLibs.srcDirs = ['native/libs']java.srcDirs = ['java/src']res.srcDirs = ['java/res']manifest.srcFile 'java/AndroidManifest.xml'}}//publishing {// singleVariant('release') {// withSourcesJar()// withJavadocJar()// }//}externalNativeBuild {cmake {path (project.projectDir.toString() + '/libcxx_helper/CMakeLists.txt')}}
}//publishing {
// publications {
// release(MavenPublication) {
// groupId = 'org.opencv'
// artifactId = 'opencv'
// version = '4.10.0'
//
// afterEvaluate {
// from components.release
// }
// }
// }
// repositories {
// maven {
// name = 'myrepo'
// url = "${project.buildDir}/repo"
// }
// }
//}
//
//dependencies {
//}
- app 调用:
public Mat onCameraFrame(Mat inputFrame) {Mat frame = inputFrame;Mat gray = new Mat();Mat edges = new Mat();List<MatOfPoint> contours = new ArrayList<>();// Convert to grayscaleImgproc.cvtColor(frame, gray, Imgproc.COLOR_RGBA2GRAY);// Apply Canny edge detectionImgproc.Canny(gray, edges, 100, 200);// Find contoursImgproc.findContours(edges, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);// Draw contours in redScalar redColor = new Scalar(255, 0, 0, 255); // RGBA: RedImgproc.drawContours(frame, contours, -1, redColor, 2);// Release temporary Mats//gray.release();//edges.release();return frame;}
运行效果:
一些问题
-
如果LOG找不到libc++_shared.so
22.0.7026061/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_shared.so
把这个文件拷贝到app的目录下:
src/main/jniLibs/armeabi-v7a/libc++_shared.so
完整代码
OpenCV 4.10.0 移植 - Android 参考调用示例代码
参考
[Ubuntu 16.04][Anaconda3][OpenCV_Contrib 4.0.1]编译OpenCV4Android
Ubuntu 编译 OpenCV SDK for Android + Linux
OpenCV 4.10.0 移植