Il y a beaucoup de questions et de réponses sur la manière d’obtenir correctement l’openv natif pour Android. Certains utilisent gradle, d'autres utilisent des outils externes. Ces descriptions nombreuses, complexes et souvent contradictoires pour les versions OpenCV natives peuvent être simplifiées avec un point de départ cohérent; lors de la création d'un projet bêta d'Android Studio 2.2, il existe un moyen d'inclure le support C++:
Cette fonctionnalité a été ajoutée aux environs de juin 2016. Voir Documentation technique sur les outils Android pour plus d'informations.
À l'aide d'Android Studio 2.2 ou version ultérieure avec le plugin Android pour Gradle version 2.2.0 ou ultérieure, vous pouvez ajouter du code C et C++ à votre application en le compilant dans une bibliothèque native que Gradle peut conditionner avec votre APK. Votre code Java peut ensuite appeler des fonctions de votre bibliothèque native via l'interface JNI (Java Native Interface). Si vous souhaitez en savoir plus sur l’utilisation du framework JNI, lisez les astuces JNI pour Android.
La vérification de Include C++ Support
génère un fichier de construction externe appelé 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} )
Pour reconnaître un projet Android utilisant le code OpenCV natif (C++), le projet comprend généralement un fichier *.cpp
contenant des entrées JNIEXPORT
ainsi que des implémentations utilisant la fonctionnalité #include <opencv...hpp>
. Ceci, par opposition à l'importation du module OpenCV et à la copie du dossier libs dans jniLibs, qui permet uniquement d'appeler la fonctionnalité OpenCV à partir de Java.
Est-il possible d'utiliser ce point de départ pour configurer une application native «Bonjour tout le monde» OpenCV, prouvant que la construction fonctionne?
INFORMATIONS COMPLEMENTAIRES 8/22
Comme ce casse-tête concerne à peu près CMake
et moins d’OpenCV, j’ai pensé donner un point de départ au projet pour ceux qui ne s'intéressent pas à OpenCV. Vous pouvez faire avancer le projet de point de départ de manière raisonnablement rapide en utilisant les informations contenues dans OpenCV dans Android Studio .
Voici une vidéo youtube qui montre la création d'un nouveau projet Android Studio, importation d'OpenCV, configuration de la construction C++ native, ce qui donne l'application OpenCV "hello world" égale à celle de gitHub.
INFORMATIONS COMPLEMENTAIRES 8/27
La version validée aujourd’hui, basée sur la réponse de Bruno Alexandre Krinski compile des appels OpenCV natifs: https://github.com/sengsational/HelloCv . Il existe un problème distinct concernant le message "Installation bloquée", où, lors de l'installation, Android avertit l'utilisateur "Cette application contient du code qui tente de contourner les protections de sécurité d'Android." Puisque je ne suis pas sûr qu'il s'agisse d'un problème avec la technique de construction, je ne développerai pas cette question pour inclure ce problème (mais si quelqu'un a des commentaires sur ce problème, merci de le signaler).
#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)
Il semble que vous ayez déjà importé le module opencv. Maintenant, ouvrez votre CMakeList.txt et ajoutez les lignes suivantes:
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")
et éditez le:
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} )
d'inclure votre lib_opencv que vous avez créé. Pour finir, vous ajoutez la ligne suivante:
abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'mips', 'mips64'
dans votre application de module, comme ceci:
externalNativeBuild {
cmake {
cppFlags "-std=c++11 -frtti -fexceptions"
abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'mips', 'mips64'
}
}
et ci-dessous de buildTypes que vous ajoutez:
sourceSets {
main {
jniLibs.srcDirs = ['path to your application /MyApplication/app/src/main/jniLibs/']
}
}
Pour plus d'informations, vous pouvez voir ceci: https://github.com/googlesamples/Android-ndk/tree/master/cmake/hello-libs
Avec OpenCV 3.2, la configuration pourrait être relativement courte:
set(OpenCV_STATIC ON)
set(OpenCV_DIR ${OPENCV_HOME}/sdk/native/jni)
find_package (OpenCV REQUIRED)
target_link_libraries(native-lib ${OpenCV_LIBS})
C'est tout, 4 lignes et pas besoin de copier quoi que ce soit dans votre projet. Assurez-vous simplement que OPENCV_HOME
pointe vers le répertoire dans lequel se trouve OpenCV Android SDK.
Un avantage supplémentaire de cette approche: vous pouvez établir une liaison statique avec OpenCV, ce qui réduirait considérablement la taille de votre application/bibliothèque.
J'utilise cette approche dans l'un des projets Github: https://github.com/Fotoapparat/FaceDetector
Les ABI [armeabi] ne sont pas pris en charge par la plateforme Android
Les ABI prises en charge sont [arm64-v8a, armeabi-v7a, x86, x86_64].
externalNativeBuild {
cmake {
// cppFlags ""
cppFlags "-std=c++11 -frtti -fexceptions"
// abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'mips', 'mips64'
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
}
}
Faites la même chose que la réponse de Bruno Alexandre Krinski mais
à la place de cette ligne
abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'mips', 'mips64'
mettre cette ligne, (je ne sais pas pourquoi cela a fonctionné pour moi)
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
(Suivez toutes les instructions de la réponse ci-dessus sauf celle-ci)