android opencv cmake java-native-interface

Agregar OpenCV al código nativo de C a través de CMake en Android Studio



java-native-interface (3)

Estoy tratando de incluir Opencv en mi código C nativo en un proyecto de estudio de Android a través de Cmake. Investigué un poco en línea y descargué el archivo FindOpenCV.cmake en línea y lo agregué al directorio de aplicaciones de mi proyecto de Android. Aquí también se encuentra CMakeLists.txt. Importé OpenCV en mi proyecto de Android Studio como módulo usando este tutorial: https://www.learn2crack.com/2016/03/setup-opencv-sdk-android-studio.html , y cuando ejecuto:

if(!OpenCVLoader.initDebug()){ System.out.println("Opencv not loaded"); } else { System.out.println("Opencv loaded"); }

Entiendo que Opencv está cargado.

Sin embargo, dado que estoy tratando de agregar OpenCV a mi código nativo, y no al código Java, no creo que pueda usar esto. Aquí están las CMakeLists que tengo ahora:

# Sets the minimum version of CMake required to build your native library. # This ensures that a certain set of CMake features is available to # your build. cmake_minimum_required(VERSION 3.4.1) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} FindOpenCV.cmake) # Specifies a library name, specifies whether the library is STATIC or # SHARED, and provides relative paths to the source code. You can # define multiple libraries by adding multiple add.library() commands, # and CMake builds them for you. When you build your app, Gradle # automatically packages shared libraries with your APK. add_library(# Specifies the name of the library. apriltag # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). src/main/apriltag/apriltag.c src/main/apriltag/apriltag_jni.c src/main/apriltag/apriltag_quad_thresh.c src/main/apriltag/common/g2d.c src/main/apriltag/common/getopt.c src/main/apriltag/common/homography.c src/main/apriltag/common/image_f32.c src/main/apriltag/common/image_u8.c src/main/apriltag/common/image_u8x3.c src/main/apriltag/common/matd.c src/main/apriltag/common/pnm.c src/main/apriltag/common/string_util.c src/main/apriltag/common/svd22.c src/main/apriltag/common/time_util.c src/main/apriltag/common/unionfind.c src/main/apriltag/common/workerpool.c src/main/apriltag/common/zarray.c src/main/apriltag/common/zhash.c src/main/apriltag/common/zmaxheap.c src/main/apriltag/tag16h5.c src/main/apriltag/tag25h7.c src/main/apriltag/tag25h9.c src/main/apriltag/tag36artoolkit.c src/main/apriltag/tag36h10.c src/main/apriltag/tag36h11.c ) STRING(REPLACE "-O0" "-O4" CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG}) STRING(REPLACE "-O2" "-O4" CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE}) include_directories(src/main/apriltag/) include_directories(${OpenCV_INCLUDE_DIRS}) find_package(OpenCV REQUIRED) find_library(log-lib log) find_library(jnigraphics-lib jnigraphics) target_link_libraries(apriltag ${log-lib} ${jnigraphics-lib})

Aquí están los errores que obtengo al construir el gradle:

By not providing "FindOpenCV.cmake" in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by "OpenCV", but CMake did not find one. Could not find a package configuration file provided by "OpenCV" with any of the following names: OpenCVConfig.cmake opencv-config.cmake Add the installation prefix of "OpenCV" to CMAKE_PREFIX_PATH or set "OpenCV_DIR" to a directory containing one of the above files. If "OpenCV" provides a separate development package or SDK, be sure it has been installed.

Entonces mis preguntas son:

  1. ¿Puedo usar el OpenCV importado o tengo que descargar un opencv diferente y almacenarlo en otro lugar?
  2. ¿Qué debo cambiar en mi CMakeLists.txt para que se construya mi gradle?

Idealmente, quiero construir y poder agregar #include <opencv2/opencv.hpp> y using namespace cv a mi archivo c y agregar funciones que usen funciones opencv.

¡Gracias por cualquier ayuda!


El método manual descrito por ahasbini funcionó ( Reg. Agregar OpenCV al código nativo C a través de CMake en Android Studio ), sin embargo, se requirieron algunos ajustes menores para la versión actual de Android Studio / SDK (3.1.3);

1 reemplace la aparición de la compile con la implementation en (10) app build.gradle ( Todavía obteniendo advertencia: la configuración de ''compilación'' está obsoleta y ha sido reemplazada por ''implementación'' ). Y en (9) la aplicación CMakeLists.txt se asegura de reemplazar YOUR_TARGET_LIB con su lib de destino (por ejemplo, native-lib ).

2 cambie el STL a gnustl_shared ( Vinculación de errores en Android con OpenCV 3.4.0 y NDK ); edit (8) app build.gradle;

defaultConfig { ... externalNativeBuild { cmake { ... arguments "-DANDROID_STL=gnustl_shared" } }

Esto evita errores de referencia dentro de bibliotecas opencv vinculadas (por ejemplo, error: undefined reference to std:: ... )

3 Para admitir C ++ 11 ( ¿Cómo habilitar C ++ 11 para Android Studio? / Problema de compilación de código nativo de Android OpenCV ); edit (8) app build.gradle;

defaultConfig { ... externalNativeBuild { cmake { ... cppFlags "-std=c++11" } }

Luego agregue lo siguiente a (9) la aplicación CMakeLists.txt antes de add_library() ;

set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs,libippicv.a -Wl,--exclude-libs,libippiw.a")

Esto evita el siguiente error; relocation R_386_GOTOFF against preemptible symbol icv_ippJumpIndexForMergedLibs cannot be used when making a shared object .


Utilicé la respuesta de @ ahasbini y produjo un error cuando quería acceder a las bibliotecas cv abiertas en mi archivo cpp nativo.

Produjo algún error al agregar las bibliotecas compartidas, pero solo si accedía a sus clases en mi archivo.

Cambiando

find_package(OpenCV REQUIRED)

A

find_package(OpenCV REQUIRED java)

Me lo arregló


ACTUALIZACIÓN 22 de mayo de 18: se agregó el paso número 6 que falta.

ACTUALIZACIÓN 10-mayo-17: la nueva solución proporciona una integración adecuada de OpenCV en la aplicación con CMake y el complemento Android Gradle 2.3.1. Probado con Android Studio 2.3.1.

ACTUALIZACIÓN 11-mayo-17: se ha proporcionado una solución adicional

Hay dos formas de incluir OpenCV.

Git / manera más simple

Visite https://github.com/ahasbini/Android-OpenCV para obtener más detalles.

Manera manual / avanzada

Para incluir las bibliotecas de OpenCV en el proyecto Android Studio, es mejor crear un nuevo módulo de biblioteca en el proyecto y transferir los archivos del paquete de Android SDK de OpenCV:

  1. Cree un nuevo módulo seleccionando Archivo> Nuevo módulo.
  2. Seleccione "Biblioteca de Android" y luego ingrese los detalles:
    • Nombre de la biblioteca: OpenCV
    • Nombre del módulo: opencv
    • Nombre del paquete: org.opencv
  3. Una vez creado el nuevo módulo, copie el contenido del directorio path_to_your_project/opencv/src/main/java path_to_opencv_sdk/sdk/java/src en path_to_your_project/opencv/src/main/java .
  4. En main , cree la siguiente ruta directa: aidl/org/opencv/engine y mueva main/java/org/opencv/engine/OpenCVEngineInterface.aidl dentro de ella.
  5. Copie el contenido de path_to_opencv_sdk/sdk/java/res en path_to_your_project/opencv/src/main/res .
  6. Cree la carpeta sdk dentro de path_to_your_project/opencv/src/ y copie la carpeta path_to_your_project/opencv/src/ path_to_opencv_sdk/sdk/native en ella.
  7. Dentro del módulo opencv , cree el archivo CMakeLists.txt y agregue las siguientes líneas en el siguiente orden:

cmake_minimum_required(VERSION 3.4.1) set(OpenCV_DIR "src/sdk/native/jni") find_package(OpenCV REQUIRED) message(STATUS "OpenCV libraries: ${OpenCV_LIBS}") include_directories(${OpenCV_INCLUDE_DIRS})

  1. Dentro del módulo opencv , edite el archivo build.gradle como tal:

... android { ... defaultConfig { minSdkVersion 8 targetSdkVersion 25 versionCode 3200 versionName "3.2.0" ... externalNativeBuild { cmake { cppFlags "-frtti -fexceptions" } } } buildTypes { ... } externalNativeBuild { cmake { path "CMakeLists.txt" } } sourceSets { main { jni.srcDirs = [jni.srcDirs, ''src/sdk/native/jni/include''] jniLibs.srcDirs = [jniLibs.srcDirs, ''src/sdk/native/3rdparty/libs'', ''src/sdk/native/libs''] } } } ...

  1. Dentro del módulo de la app (módulo de aplicación, podría ser otro nombre), cree / edite el archivo CMakeLists.txt y agregue las siguientes líneas en el siguiente orden ( OpenCV_DIR cuenta la ruta diferente establecida en OpenCV_DIR ):

set(OpenCV_DIR "../opencv/src/sdk/native/jni") find_package(OpenCV REQUIRED) message(STATUS "OpenCV libraries: ${OpenCV_LIBS}") target_link_libraries(YOUR_TARGET_LIB ${OpenCV_LIBS})

  1. Dentro del módulo de la app (módulo de aplicación, podría ser otro nombre), edite el archivo build.gradle como tal:

... android { ... defaultConfig { ... externalNativeBuild { cmake { cppFlags "-frtti -fexceptions" } } buildTypes { ... } externalNativeBuild { cmake { path "CMakeLists.txt" } } } dependencies { ... compile project('':opencv'') }

  1. Haga una sincronización de Gradle, y ahora se incluyen las bibliotecas nativas de OpenCV, los archivos de encabezado y las clases de contenedor Java.

Cuando se construye el proyecto y se inicia el apk, puede inspeccionar el apk empaquetado en path_to_project/path_to_app_module/build/output/ (arrastre el apk a las pestañas del editor de texto de Android Studio)

Debería ver un libopencv_java3.so debajo de cada carpeta de arquitectura abi.

Inicialice el SDK de OpenCV en su clase de Java:

public class MyClass { static { if (BuildConfig.DEBUG) { OpenCVLoader.initDebug(); } } ... }

Y debería ver dentro de los mensajes logcat que especifican que se ha cargado OpenCV (el primer error es normal):

05-10 10:42:31.451 D/OpenCV/StaticHelper: Trying to get library list 05-10 10:42:31.452 E/OpenCV/StaticHelper: OpenCV error: Cannot load info library for OpenCV 05-10 10:42:31.452 D/OpenCV/StaticHelper: Library list: "" 05-10 10:42:31.452 D/OpenCV/StaticHelper: First attempt to load libs 05-10 10:42:31.452 D/OpenCV/StaticHelper: Trying to init OpenCV libs 05-10 10:42:31.452 D/OpenCV/StaticHelper: Trying to load library opencv_java3 05-10 10:42:32.031 D/OpenCV/StaticHelper: Library opencv_java3 loaded 05-10 10:42:32.031 D/OpenCV/StaticHelper: First attempt to load libs is OK 05-10 10:42:32.045 I/OpenCV/StaticHelper: General configuration for OpenCV 3.2.0 ===================================== 05-10 10:42:32.045 I/OpenCV/StaticHelper: Version control: 3.2.0 05-10 10:42:32.045 I/OpenCV/StaticHelper: Platform: 05-10 10:42:32.045 I/OpenCV/StaticHelper: Timestamp: 2016-12-23T13:04:49Z 05-10 10:42:32.045 I/OpenCV/StaticHelper: Host: Linux 4.8.0-25-generic x86_64 05-10 10:42:32.045 I/OpenCV/StaticHelper: Target: Linux 1 x86_64 05-10 10:42:32.045 I/OpenCV/StaticHelper: CMake: 2.8.12.2 05-10 10:42:32.045 I/OpenCV/StaticHelper: CMake generator: Ninja 05-10 10:42:32.045 I/OpenCV/StaticHelper: CMake build tool: /usr/bin/ninja 05-10 10:42:32.045 I/OpenCV/StaticHelper: Configuration: Release 05-10 10:42:32.045 I/OpenCV/StaticHelper: C/C++: 05-10 10:42:32.045 I/OpenCV/StaticHelper: Built as dynamic libs?: NO 05-10 10:42:32.045 I/OpenCV/StaticHelper: C++ Compiler: /usr/bin/ccache /opt/android/android-ndk-r10e/toolchains/x86_64-4.9/prebuilt/linux-x86_64/bin/x86_64-linux-android-g++ (ver 4.9)