使用Android Studio 3.0 (>=2.2)和Cmake (CMakeLists)让OpenCV 3.4 飞起来

版权声明:本文为博主原创文章,转载而不修改内容请留言告知,转载并修改内容请与我联系。 https://blog.csdn.net/Martin20150405/article/details/53284442

Github项目地址
不回复有关“如何配置”的任何问题
2017-01-13 :现在已经更新到OpenCV3.2
2017-12-28 :现在已经更新到OpenCV3.4
Old versions can be downloaded from here

如果需要配置只有静态库的项目,可以去除Cmakelists中所有静态库的注释,但libopencv_java3.so是Java SDK必须的,除非不使用Java层的任何OpenCV接口,否则只能去除libopencv_java.so

如果懒得自己配,可以直接下载,包括使用Cmake作为工具的 OpenCV 3.x for Android(支持Java 和 NDK C++,不需要额外配置,不需要OpenCV Manager),提供一个简单的相机Preview demo (注意,只包含armeabi-v7a,如果需要其他类型可以参考教程自行配置

按照本教程配置大约需要10分钟

说明

自从Android Studio 2.2稳定版发布以后,对于NDK的支持变得比以前更好了(终于支持Cmake了,好感动),但是想要在Android上使用OpenCV,普遍的方式还是基于Android.mk+ndk_build或者使用gradle-experimental

目标

  • 使用Cmake来编译OpenCV 3.1 for Android,抛开Android.mk (理论上本方法也可以用于OpenCV 2.4X)
  • 同时支持Java层的OpenCV和NDK (C++)的编译,并且都有代码提示和补全
  • 移除OpenCV Manager

1. 前期准备

这部分内容引用自这里

  • 请确保你的Android Studio的版本已经升级到2.2及以上
  • 下载ndk,在File->Settings->Appearance & Behavior -> System Settings-> Android SDK下载相应的ndk
  • 在同一个位置下载CMAKE,LLDB
    这里写图片描述

2. Java的OpenCV支持

  • 创建一个新的项目,勾选 C++支持
    这里写图片描述
  • 将OpenCV下面的java文件夹 (路径为OpenCV-android-sdk\sdk\java)作为模块导入,可能需要修改gradle的版本和minSDK版本
    这里写图片描述

  • 在主模块中加入对于OpenCV Library的依赖
    这里写图片描述

  • 现在OpenCV的Java层配置已经完成,sync一下,应该已经有代码补全了
    这里写图片描述
  • 为了愉快的使用OpenCV Library,可以直接在AndroidManifest.xml里面加入如下权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>

<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<uses-feature android:name="android.hardware.camera.front" android:required="false"/>
<uses-feature android:name="android.hardware.camera.front.autofocus" android:required="false"/>

3. NDK/native (C++)的OpenCV支持

  • include文件夹(路径OpenCV-android-sdk\sdk\native\jni\include)拷贝到cpp(路径\app\src\main\cpp)文件夹里
  • 将依赖的动态库和静态库(路径为OpenCV-android-sdk\sdk\native\libs)拷贝到\src\main\jniLibs下面
  • 完成上述步骤,你的工程结构应该和下图一样
    这里写图片描述

  • 修改app的gradle,因为我们之前已经引入了C++ support,所以直接改为这样(完整gradle参见项目)

externalNativeBuild {
    cmake {
        //arguments  '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=gnustl_static'
        cppFlags "-std=c++11","-frtti", "-fexceptions"
    }
}
ndk{
    abiFilters 'armeabi-v7a'
}
  • 修改CMakeLists,这一步很重要

CMakeLists的主要作用就是告诉NDK我的源代码有哪些,要包含哪些头文件,我的第三方依赖库有哪些,要用什么方式编译

这里提供的仅供参考(直接把所有的.so和.a加进来)

cmake_minimum_required(VERSION 3.6)

set(CMAKE_VERBOSE_MAKEFILE on)
set(libs "${CMAKE_SOURCE_DIR}/src/main/jniLibs")
include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include)

add_library(libopencv_java3 SHARED IMPORTED )
set_target_properties(libopencv_java3 PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_java3.so")

add_library(libopencv_java SHARED IMPORTED )
set_target_properties(libopencv_java PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_java.so")

add_library(libopencv_calib3d STATIC IMPORTED )
set_target_properties(libopencv_calib3d PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_calib3d.a")

add_library(libopencv_core STATIC IMPORTED )
set_target_properties(libopencv_core PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_core.a")

add_library(libopencv_features2d STATIC IMPORTED )
set_target_properties(libopencv_features2d PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_features2d.a")

add_library(libopencv_flann STATIC IMPORTED )
set_target_properties(libopencv_flann PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_flann.a")

add_library(libopencv_highgui STATIC IMPORTED )
set_target_properties(libopencv_highgui PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_highgui.a")

add_library(libopencv_imgcodecs STATIC IMPORTED )
set_target_properties(libopencv_imgcodecs PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_imgcodecs.a")

add_library(libopencv_imgproc STATIC IMPORTED )
set_target_properties(libopencv_imgproc PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_imgproc.a")

add_library(libopencv_ml STATIC IMPORTED )
set_target_properties(libopencv_ml PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_ml.a")

add_library(libopencv_objdetect STATIC IMPORTED )
set_target_properties(libopencv_objdetect PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_objdetect.a")

add_library(libopencv_photo STATIC IMPORTED )
set_target_properties(libopencv_photo PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_photo.a")

add_library(libopencv_shape STATIC IMPORTED )
set_target_properties(libopencv_shape PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_shape.a")

add_library(libopencv_stitching STATIC IMPORTED )
set_target_properties(libopencv_stitching PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_stitching.a")

add_library(libopencv_superres STATIC IMPORTED )
set_target_properties(libopencv_superres PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_superres.a")

add_library(libopencv_video STATIC IMPORTED )
set_target_properties(libopencv_video PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_video.a")

add_library(libopencv_videoio STATIC IMPORTED )
set_target_properties(libopencv_videoio PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_videoio.a")

add_library(libopencv_videostab STATIC IMPORTED )
set_target_properties(libopencv_videostab PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_videostab.a")

add_library(libopencv_ts STATIC IMPORTED )
set_target_properties(libopencv_ts PROPERTIES
    IMPORTED_LOCATION "${libs}/${ANDROID_ABI}/libopencv_ts.a")

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11 -fexceptions -frtti")


#include_directories(D:/Projects/Android/CLMAndroid/OpenCV-android-sdk/sdk/native/jni/include )
#set(OpenCV_DIR D:/Projects/Android/CLMAndroid/OpenCV-android-sdk/sdk/native/jni)
#find_package(OpenCV REQUIRED)
#target_link_libraries(${OpenCV_LIBS})

add_library( # Sets the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             # Associated headers in the same location as their source
             # file are automatically included.
             src/main/cpp/native-lib.cpp )

find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log)

target_link_libraries(native-lib android log
    libopencv_java3 libopencv_java libopencv_calib3d libopencv_core libopencv_features2d libopencv_flann libopencv_highgui libopencv_imgcodecs
    libopencv_imgproc libopencv_ml libopencv_objdetect libopencv_photo libopencv_shape libopencv_stitching libopencv_superres
    libopencv_video libopencv_videoio libopencv_videostab
    ${log-lib}
    )

同步或者rebuild一下,应该也已经有代码补全了,C++层的配置到此为止,是不是很方便?
这里写图片描述

去除OpenCV Manager

OpenCV Manager的作用是提供一些公共的动态链接库,但是要多装一个Apk确实是很烦的事情

  • OpenCV Manager中的动态链接库主要有这些,我们把最后两个拷到jniLibs下面就好(native_camera 估计是给C++层打开相机用的,因为相机Preview一般都是用Java层的,所以可以不用加,如果使用相机的时候出现了问题,可以加进去试试)
    这里写图片描述

  • 因为去除了OpenCV Manager,我们要自己加载类库,注意加载的顺序,native-lib就是刚才我们自己写的cpp编译的结果

static {
    System.loadLibrary("opencv_java3");
    System.loadLibrary("opencv_java");
    System.loadLibrary("native-lib");
}

这样,我们就成功移除了OpenCV Manager

关于so文件位置

这个项目中jniLibs是和CmakeLists相关联的文件夹,在最新的AS版本上会被自动打包进本Module的APK,如果发现没有打包进去,可以尝试修改lib路径为指定路径

sourceSets.main {
        jniLibs.srcDirs = ['libs']
        jni.srcDirs = []
}

教程到此全部结束,愉快的使用Cmake,让你的OpenCV飞起来吧~

关于测试的demo(demo就是sample2,用来做相机预览和特征点检测的),请在项目中查看,我稍微修改了Java类库,加了一个相机的触摸对焦

这里写图片描述

Github项目地址

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试