Android集成OpenCV并减少库大小

前言


最近完成了Android上使用OpenCV进行图像拼接的功能,通过导入OpenCV的.so或.a库,JNI封装C++代码供Java层调用,同时在CMakeLists中指定自己需要的.a库以减少库的大小,毕竟我只用了拼接功能,其它诸如dnn、video等模块我都没用到。
在开始之前当然要把OpenCV Android SDK下载下来,推荐去GitHub下载,在OpenCV官网下载真是龟速,链接
环境:OpenCV 3.3.1 、Android Studio 3.0

步骤


1.添加OpenCV-android-sdk

将OpenCV-android-sdk\sdk\native文件夹添加到项目中,这里我把native重命名为opencv,如下图:

其中3rdparty包含opencv使用的第三方库,jni/include包含opencv的头文件
,libs包含opencv编译好的动态库与静态库。

2.修改build.gradle

如图,添加红框中的内容,其中abiFilters 'armeabi'表示只生成armeabi架构的包,若不指定则会生成全部架构。

注意:确保你当前的工程已启用C++支持,如果没有就重新建一个项目并勾选Include C++ Support,我也尝试过创建普通Android工程,是build不过的,想启用C++支持也没找到方法,只好重新建一个包含C++支持的项目了。

3.修改CMakeLists.txt

# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)

# 包含opencv的头文件
include_directories(opencv/jni/include)

# 静态方式导入库
add_library(opencv_calib3d STATIC IMPORTED)
add_library(opencv_core STATIC IMPORTED)
add_library(opencv_features2d STATIC IMPORTED)
add_library(opencv_flann STATIC IMPORTED)
add_library(opencv_imgcodecs STATIC IMPORTED)
add_library(opencv_imgproc STATIC IMPORTED)
add_library(opencv_stitching STATIC IMPORTED)

add_library(cpufeatures STATIC IMPORTED)
add_library(IlmImf STATIC IMPORTED)
add_library(libjasper STATIC IMPORTED)
add_library(libjpeg STATIC IMPORTED)
add_library(libpng STATIC IMPORTED)
#add_library(libprotobuf STATIC IMPORTED)
add_library(libtiff STATIC IMPORTED)
add_library(libwebp STATIC IMPORTED)
add_library(tbb STATIC IMPORTED)
add_library(tegra_hal STATIC IMPORTED)

# 设置库路径
set_target_properties(opencv_calib3d PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/opencv/libs/${ANDROID_ABI}/libopencv_calib3d.a)
set_target_properties(opencv_core PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/opencv/libs/${ANDROID_ABI}/libopencv_core.a)
set_target_properties(opencv_features2d PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/opencv/libs/${ANDROID_ABI}/libopencv_features2d.a)
set_target_properties(opencv_flann PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/opencv/libs/${ANDROID_ABI}/libopencv_flann.a)
set_target_properties(opencv_imgcodecs PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/opencv/libs/${ANDROID_ABI}/libopencv_imgcodecs.a)
set_target_properties(opencv_imgproc PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/opencv/libs/${ANDROID_ABI}/libopencv_imgproc.a)
set_target_properties(opencv_stitching PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/opencv/libs/${ANDROID_ABI}/libopencv_stitching.a)

set_target_properties(cpufeatures PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/opencv/3rdparty/libs/${ANDROID_ABI}/libcpufeatures.a)
set_target_properties(IlmImf PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/opencv/3rdparty/libs/${ANDROID_ABI}/libIlmImf.a)
set_target_properties(libjasper PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/opencv/3rdparty/libs/${ANDROID_ABI}/liblibjasper.a)
set_target_properties(libjpeg PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/opencv/3rdparty/libs/${ANDROID_ABI}/liblibjpeg.a)
set_target_properties(libpng PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/opencv/3rdparty/libs/${ANDROID_ABI}/liblibpng.a)
#set_target_properties(libprotobuf PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/opencv/3rdparty/libs/${ANDROID_ABI}/liblibprotobuf.a)
set_target_properties(libtiff PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/opencv/3rdparty/libs/${ANDROID_ABI}/liblibtiff.a)
set_target_properties(libwebp PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/opencv/3rdparty/libs/${ANDROID_ABI}/liblibwebp.a)
set_target_properties(tbb PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/opencv/3rdparty/libs/${ANDROID_ABI}/libtbb.a)
set_target_properties(tegra_hal PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/opencv/3rdparty/libs/${ANDROID_ABI}/libtegra_hal.a)

set(SRC_DIR src/main/cpp)

file(GLOB_RECURSE CPP_SRCS "${SRC_DIR}/*.cpp")  #指定当前目录下的所有.cpp文件(包括子目录)

add_library( # Sets the name of the library.
             MyStitch

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             ${CPP_SRCS} )

# 链接库,注意被依赖的库放后面
target_link_libraries( # Specifies the target library.
                       MyStitch                       

                       opencv_stitching
                       opencv_features2d
                       opencv_flann
                       opencv_imgcodecs                       
                       opencv_imgproc
                       opencv_core
                       opencv_calib3d

                       IlmImf
                       cpufeatures
                       libjasper
                       libjpeg
                       libpng
                       #libprotobuf
                       libtiff
                       libwebp
                       tbb
                       tegra_hal

                       # included in the NDK.
                       jnigraphics
                       log )

这些库都是拼接所必需的,自己尝试了好多次才成功。其实思路很简单,用add_libraryset_target_properties导入需要的库,最后在target_link_libraries中全部链接,值得注意的是最终链接库时被依赖的库要放后面,顺序不能搞错了。
如果要使用opencv全部的功能,官方也已经为我们制作了libopencv_java3.so库,只用导入这一个就行了。

4.调用opencv

在cpp文件夹下添加你自己的代码文件,就可以用C++调用opencv了,话说用AS写C++体验还是蛮好的。之后你还需要用JNI封装C++方法,以供Java层调用,不过这不在本文的讨论范围之内。

后记


完成后我得到的aar包大小为2.5MB,包含全部功能的libopencv_java3.so为10MB多,Mission Completed!

猜你喜欢

转载自blog.csdn.net/suwk1009/article/details/79746724