使用Android Studio 2.2和Cmake (CMakeLists)让OpenCV 飞起来

来源:互联网 发布:coupang java招聘 编辑:程序博客网 时间:2024/05/20 07:52

Github项目地址
不回复有关“如何配置”的任何问题
2017-01-13 :现在已经更新到OpenCV3.2

如果懒得自己配,可以直接下载,包括使用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"/>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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'}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 修改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}    )
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115

同步或者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");}
  • 1
  • 2
  • 3
  • 4
  • 5

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

关于so文件位置

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

sourceSets.main {        jniLibs.srcDirs = ['libs']        jni.srcDirs = []}
  • 1
  • 2
  • 3
  • 4

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

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

这里写图片描述

Github项目地址

原创粉丝点击