【发布时间】:2016-12-21 21:11:15
【问题描述】:
关于如何正确构建用于 android 的原生 opencv 有很多问题和答案。有些使用 gradle,有些使用外部工具。这些对原生 OpenCV 构建的众多、复杂且经常相互冲突的描述可以通过一致的起点进行简化;在创建 Android Studio 2.2 Beta 项目时,有一种方法可以包含 C++ 支持:
此功能是在 2016 年 6 月左右添加的。有关详细信息,请参阅 Android tools technical docs。
将 Android Studio 2.2 或更高版本与适用于 Gradle 版本 2.2.0 或更高版本的 Android 插件结合使用,您可以将 C 和 C++ 代码添加到您的应用中,方法是将其编译到 Gradle 可以与您的 APK 一起打包的本机库中。然后,您的 Java 代码可以通过 Java 本机接口 (JNI) 调用本机库中的函数。如果您想了解有关使用 JNI 框架的更多信息,请阅读适用于 Android 的 JNI 提示。
检查Include C++ Support 会生成一个名为CMakeLists.txt 的外部构建文件。
# Sets the minimum version of CMake required to build the native
# library. You should either keep the default value or only pass a
# value of 3.4.0 or lower.
cmake_minimum_required(VERSION 3.4.1)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds it for you.
# Gradle automatically packages shared libraries with your APK.
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 )
# Searches for a specified prebuilt library and stores the path as a
# variable. Because system libraries are included in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
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 )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in the
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
$\{log-lib} )
要识别使用本机 (C++) OpenCV 代码的 Android 项目,该项目通常会包含一个 *.cpp 文件,其中包含 JNIEXPORT 条目以及使用 #include <opencv...hpp> 功能的实现。这与导入 OpenCV 模块并将 libs 文件夹复制到 jniLibs 不同,后者仅允许从 Java 调用 OpenCV 功能。
是否可以使用此起点配置 OpenCV 原生“hello world”应用程序,证明构建工作正常?
附加信息 8/22
由于这个谜题是关于CMake 而不是关于OpenCV,我想我会为那些对OpenCV 不感兴趣的人提供一个项目起点。使用OpenCV in Android Studio 中的信息,您可以合理快速地启动起点项目。
这是一个youtube video,它显示了一个新的 Android Studio 项目的创建、导入 OpenCV、配置本地 C++ 构建,从而生成了与 gitHub 中的相同的 OpenCV“hello world”应用程序。
附加信息 8/27
今天提交的版本,基于 Bruno Alexandre Krinski 的回答确实编译本机 OpenCV 调用:https://github.com/sengsational/HelloCv。关于“安装被阻止”消息还有一个单独的问题,在安装时,Android 会警告用户“此应用包含试图绕过 Android 安全保护的代码”。由于我不确定这是构建技术的问题,因此我不会扩展此问题以包含该问题(但如果有人对此问题有意见,请告知)。
#Added 2 path definitions to support 20160825 additions
set(pathToProject C:/Users/Owner/AndroidStudioProjects/HelloCv)
set(pathToOpenCv C:/Users/Owner/OpenCV-3.1.0-android-sdk)
#Added by the IDE on project create
cmake_minimum_required(VERSION 3.4.1)
#Two sets suggested by Bruno Alexandre Krinski 20160825
set(CMAKE_VERBOSE_MAKEFILE on)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
#Addition suggested by Bruno Alexandre Krinski 20160825
include_directories(${pathToOpenCv}/sdk/native/jni/include)
#Added by IDE on project create
add_library( native-lib SHARED src/main/cpp/native-lib.cpp )
#Addition suggested by Bruno Alexandre Krinski 20160825
add_library( lib_opencv SHARED IMPORTED )
#Addition suggested by Bruno Alexandre Krinski 20160825
set_target_properties(lib_opencv PROPERTIES IMPORTED_LOCATION ${pathToProject}/app/src/main/jniLibs/${ANDROID_ABI}/libopencv_java3.so)
#Added by IDE on project create
find_library( log-lib log )
#Added by IDE on project create, Removed and replace with additional parameter suggested by Bruno Alexandre Krinski 20160825
#target_link_libraries( native-lib $\{log-lib} )
target_link_libraries( native-lib $\{log-lib} lib_opencv)
【问题讨论】:
-
您的 OpenCV build.gradle 文件是什么样的?我们需要知道这些是您正在编译的静态库还是共享库。
-
它看起来并没有做任何有趣的事情:github.com/sengsational/HelloCv/blob/master/openCVLibrary310/…
-
OpenCV 团队提供了更多关于在 Android 上执行本机代码的信息:docs.opencv.org/doc/tutorials/introduction/…
-
我明白了,所以他们使用的是 Android.mk 而不是 Gradle-experimental NDK。因此,在这种情况下,您使用 Cmake 的方法很好。
-
这个问题真的很好。我遇到的一些 AndroidNDK/OpenCV 教程采用了一种繁琐的方法(参见youtube.com/watch?v=Oq3oiCfSgbo),您必须在其中编译 jni 标头等,并且失去了 Android Studio 的 IntelliJ 魔法的力量。为问题 +1,为以下答案 +1。
标签: windows android-studio cmake java-native-interface opencv4android