OpenCV for Android可以利用标准C++支持在Android Studio 2.2 for Windows上获得本机构建支持吗?

Dal*_*ale 27 windows java-native-interface cmake android-studio opencv4android

围绕获取原生opencv for android构建有很多问题和答案.有些使用gradle,有些则使用外部工具.对于原生OpenCV构建,这些众多,复杂且经常相互矛盾的描述可能会以一致的起点进行简化; 在创建Android Studio 2.2 Beta项目时,有一种方法可以包含C++支持: 包括C++支持在此输入图像描述

此功能是在2016年6月左右添加的.有关详细信息,请参阅Android工具技术文档.

将Android Studio 2.2或更高版本与Gradle 2.2.0或更高版本的Android插件一起使用,您可以将C和C++代码编译到Gradle可以与您的APK打包的本机库中,从而为您的应用添加C和C++代码.然后,您的Java代码可以通过Java Native Interface(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} )
Run Code Online (Sandbox Code Playgroud)

要识别使用本机(C++)OpenCV代码的Android项目,项目通常会包含一个*.cpp包含JNIEXPORT条目的文件以及使用#include <opencv...hpp>功能的实现.这与导入OpenCV模块并将libs文件夹复制到jniLibs相反,后者只允许从Java调用OpenCV功能.

是否可以使用此起点配置OpenCV本机"hello world"应用程序,证明构建工作正常?

其他信息8/22
由于这个难题CMake与OpenCV有关,我想我会给那些对OpenCV不感兴趣的人一个项目起点.您可以使用Android Studio中的OpenCV中的信息快速合理地启动起点项目.

这是一个YouTube视频,显示了新的Android Studio项目的创建,导入OpenCV,配置本机C++构建,导致OpenCV"hello world"应用程序等同于gitHub中的应用程序.

其他信息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)
Run Code Online (Sandbox Code Playgroud)

小智 24

看来你已经导入了opencv模块,现在,打开你的CMakeList.txt并添加以下行:

set(CMAKE_VERBOSE_MAKEFILE on)

add_library(lib_opencv SHARED IMPORTED)

set_target_properties(lib_opencv PROPERTIES IMPORTED_LOCATION
path-to-your-project/MyApplication/app/src/main/jniLibs/${ANDROID_ABI}/libopencv_java3.so)


include_directories(path-to-opencv-directory/OpenCV-android-sdk/sdk/native/jni/include)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
Run Code Online (Sandbox Code Playgroud)

并编辑:

target_link_libraries( # Specifies the target library.
                   native-lib
                   lib_opencv
                   # Links the target library to the log library
                   # included in the NDK.
                   $\{log-lib} )
Run Code Online (Sandbox Code Playgroud)

包括您创建的lib_opencv.要完成,请添加以下行:

abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'mips', 'mips64'
Run Code Online (Sandbox Code Playgroud)

在您的模块应用中,如下所示:

externalNativeBuild {

    cmake {
        cppFlags "-std=c++11 -frtti -fexceptions"
        abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'mips', 'mips64'
    }
}
Run Code Online (Sandbox Code Playgroud)

以及您添加的buildTypes的下方:

sourceSets {
    main {
        jniLibs.srcDirs = ['path to your application /MyApplication/app/src/main/jniLibs/']
    }
}
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅:https://github.com/googlesamples/android-ndk/tree/master/cmake/hello-libs

  • 为什么要写`$\{log-lib}`而不是`$ {log-lib}`? (2认同)

Dmi*_*sev 8

使用OpenCV 3.2配置实际上可能很短:

set(OpenCV_STATIC ON)
set(OpenCV_DIR ${OPENCV_HOME}/sdk/native/jni)
find_package (OpenCV REQUIRED)

target_link_libraries(native-lib ${OpenCV_LIBS})
Run Code Online (Sandbox Code Playgroud)

就是这样,4行,无需将任何内容复制到您的项目中.请确保OPENCV_HOME指向OpenCV Android SDK所在的目录.

这种方法的另一个好处是 - 您可以静态链接OpenCV,这将大大减少您的应用程序/库的大小.

我在Github项目中使用这种方法:https://github.com/Fotoapparat/FaceDetector

  • 这是我能找到的唯一解决方案,可以在Android上使用C++中的OpenCV库进行构建.您的FaceDetector应用程序对我来说是一个非常有用的参考,试图解决我的问题.非常感谢你! (2认同)