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一文:

  1. 弥补缺少java文件输出
  2. 使用Gradle
  3. 增加示例测试
环境
属性
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的下载解压, 前文已有, 不在赘述.

构建的方法有两种:

  1. 使用python脚本
  2. 使用传统的make
bash 复制代码
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.cmake

withPython=0

output_dir=build-android
if [ ! -d $output_dir ]; then
    mkdir $output_dir
fi


for arg in $@; do
    if [ $arg == "clean" ]; then
        echo "build with clean"
        rm -rf $output_dir/*
    elif [ $arg == "python" ]; then
        echo "build via python"
        withPython=1;
    fi

done

## -------------------- ##
cd $output_dir

echo "START Configure..."
echo "build via python is $withPython"


## OK
if [ $withPython == "1" ]; then
    python ../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 \
     . \
     ..
else
    abis="armeabi-v7a arm64-v8a"
    for abi in $abis; do
        echo "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_modules
        make -j12
        make install
    done
fi

echo "--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

  1. settings.gradle 增加OpenCV模块
gradle 复制代码
include ':opencv-4.10'
project(':opencv-4.10').projectDir = new File("opencv-4.10.0/build-android/install/sdk")
  1. app模块增加依赖

build.gradle

cpp 复制代码
apply plugin: 'com.android.application'
android {
    defaultConfig {
    	//省略app信息
        externalNativeBuild{
            ndk{
                abiFilters 'armeabi-v7a'
            }
        }
    }
}
dependencies {
    implementation project(':opencv-4.10')
}
  1. 导入OpenCV出错, 参照下文注释部分配置:
cpp 复制代码
// 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 + 0

println "OpenCV: " +openCVersionName + " " + project.buildscript.sourceFile

android {

    compileSdkVersion 31

    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 31

        versionCode openCVersionCode
        versionName openCVersionName

        externalNativeBuild {
            cmake {
                arguments "-DANDROID_STL=c++_shared"
                targets "opencv_jni_shared"
            }
        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    buildTypes {
        debug {
            packagingOptions {
                doNotStrip '**/*.so'  // controlled by OpenCV CMake scripts
            }
        }
        release {
            packagingOptions {
                doNotStrip '**/*.so'  // controlled by OpenCV CMake scripts
            }
            minifyEnabled false
            proguardFiles 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 {
//}
  1. app 调用:
java 复制代码
    public Mat onCameraFrame(Mat inputFrame) {
        Mat frame = inputFrame;
        Mat gray = new Mat();
        Mat edges = new Mat();
        List<MatOfPoint> contours = new ArrayList<>();

        // Convert to grayscale
        Imgproc.cvtColor(frame, gray, Imgproc.COLOR_RGBA2GRAY);

        // Apply Canny edge detection
        Imgproc.Canny(gray, edges, 100, 200);

        // Find contours
        Imgproc.findContours(edges, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

        // Draw contours in red
        Scalar redColor = new Scalar(255, 0, 0, 255); // RGBA: Red
        Imgproc.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 移植

相关推荐
梦否4 分钟前
Android 代码热度统计(概述)
android
charley.layabox5 分钟前
8月1日ChinaJoy酒会 | 游戏出海高端私享局 | 平台 × 发行 × 投资 × 研发精英畅饮畅聊
人工智能·游戏
DFRobot智位机器人42 分钟前
AIOT开发选型:行空板 K10 与 M10 适用场景与选型深度解析
人工智能
想成为风筝3 小时前
从零开始学习深度学习—水果分类之PyQt5App
人工智能·深度学习·计算机视觉·pyqt
F_D_Z3 小时前
MMaDA:多模态大型扩散语言模型
人工智能·语言模型·自然语言处理
大知闲闲哟3 小时前
深度学习G2周:人脸图像生成(DCGAN)
人工智能·深度学习
xchenhao3 小时前
基于 Flutter 的开源文本 TTS 朗读器(支持 Windows/macOS/Android)
android·windows·flutter·macos·openai·tts·朗读器
飞哥数智坊3 小时前
Coze实战第15讲:钱都去哪儿了?Coze+飞书搭建自动记账系统
人工智能·coze
wenzhangli74 小时前
低代码引擎核心技术:OneCode常用动作事件速查手册及注解驱动开发详解
人工智能·低代码·云原生
coder_pig4 小时前
跟🤡杰哥一起学Flutter (三十五、玩转Flutter滑动机制📱)
android·flutter·harmonyos