前言

最近完成了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,如下图:

2a6943a3c839acba05e5d0f54c82de55.png

其中3rdparty包含opencv使用的第三方库,jni/include包含opencv的头文件

,libs包含opencv编译好的动态库与静态库。

2.修改build.gradle

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

1e717cc3cbf00da748e53cb30b031fa9.png

注意:确保你当前的工程已启用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_library和set_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!

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐