如何在Android Studio 3.1.2中添加原生OpenCV?

时间:2018-05-05 12:20:00

标签: android c++ opencv cmake android-ndk

我的Android Studio版本是3.1.2,Java版本是1.8

我使用以下步骤将OpenCV添加到项目

  1. 创建新项目并检查"包括C ++支持",在自定义C ++支持选项中,我使用此选项

    • C ++标准:工具链默认

    • 例外支持:不检查

    • 运行时类型信息支持:不检查

  2. 下载OpenCV 3.4.1并解压缩到C:\OpenCV-android-sdk

  3. 将CMakeLists.txt编辑到此

  4. cmake_minimum_required(VERSION 3.4.1)
    
    # ##################### OpenCV ############################
    
    set( OpenCV_DIR C:/OpenCV-android-sdk/sdk/native/jni )
    
    find_package(OpenCV REQUIRED )
    if(OpenCV_FOUND)
        include_directories(${OpenCV_INCLUDE_DIRS})
        message(STATUS "OpenCV library status:")
        message(STATUS "    version: ${OpenCV_VERSION}")
        message(STATUS "    libraries: ${OpenCV_LIBS}")
        message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")
    else(OpenCV_FOUND)
        message(FATAL_ERROR "OpenCV library not found")
    endif(OpenCV_FOUND)
    
    # ###################### End OpenCV ###########################
    
    
    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).
                 src/main/cpp/native-lib.cpp )
    
    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 )
    
    target_link_libraries( # Specifies the target library.
                           native-lib
    
                            ${OpenCV_LIBS}
                           # Links the target library to the log library
                           # included in the NDK.
                           ${log-lib} )
    

    现在,如果我重建项目,它仍然是成功的,OpenCV也在项目中添加了

    enter image description here

    如果我将include添加到native-lib.cpp,我无法构建项目,有什么问题?

    #include <jni.h>
    #include <string>
    #include <opencv2/opencv.hpp> // or #include "opencv2/opencv.hpp"
    
    extern "C" JNIEXPORT jstring
    
    JNICALL
    Java_com_test_cv_MainActivity_stringFromJNI(
            JNIEnv *env,
            jobject /* this */) {
        std::string hello = "Hello from C++";
        return env->NewStringUTF(hello.c_str());
    }
    

    我得到的错误:

    Build command failed.
    Error while executing process C:\Users\me\AppData\Local\Android\Sdk\cmake\3.6.4111459\bin\cmake.exe with arguments {--build R:\Cv\app\.externalNativeBuild\cmake\debug\x86 --target native-lib}
    [1/2] Building CXX object CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o
    [2/2] Linking CXX shared library ..\..\..\..\build\intermediates\cmake\debug\obj\x86\libnative-lib.so
    FAILED: cmd.exe /C "cd . && C:\Users\me\AppData\Local\Android\Sdk\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe  --target=i686-none-linux-android --gcc-toolchain=C:/Users/so/AppData/Local/Android/Sdk/ndk-bundle/toolchains/x86-4.9/prebuilt/windows-x86_64 --sysroot=C:/Users/so/AppData/Local/Android/Sdk/ndk-bundle/sysroot -fPIC -isystem C:/Users/so/AppData/Local/Android/Sdk/ndk-bundle/sysroot/usr/include/i686-linux-android -D__ANDROID_API__=21 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -mstackrealign -Wa,--noexecstack -Wformat -Werror=format-security   -O0 -fno-limit-debug-info  -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a --sysroot C:/Users/so/AppData/Local/Android/Sdk/ndk-bundle/platforms/android-21/arch-x86 -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libnative-lib.so -o ..\..\..\..\build\intermediates\cmake\debug\obj\x86\libnative-lib.so CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o  C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_highgui.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_features2d.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_shape.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_imgcodecs.a C:/OpenCV-android-sdk/sdk/native................
    

    更新错误消息

    org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:externalNativeBuildDebug'.
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:100)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:70)
        at org.gradle.api.internal.tasks.execution.OutputDirectoryCreatingTaskExecuter.execute(OutputDirectoryCreatingTaskExecuter.java:51)
        at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:62)
        at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54)
        at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:60)
        at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:97)
        at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:87)
        at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:52)
        at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
        at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)
        at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
        at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.run(DefaultTaskGraphExecuter.java:248)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:241)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:230)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.processTask(DefaultTaskPlanExecutor.java:123)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.access$200(DefaultTaskPlanExecutor.java:79)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:104)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:98)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.execute(DefaultTaskExecutionPlan.java:626)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.executeWithTask(DefaultTaskExecutionPlan.java:581)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.run(DefaultTaskPlanExecutor.java:98)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
        at java.lang.Thread.run(Thread.java:745)
    Caused by: org.gradle.internal.UncheckedException: Build command failed.
    Error while executing process C:\Users\me\AppData\Local\Android\Sdk\cmake\3.6.4111459\bin\cmake.exe with arguments {--build R:\Cv\app\.externalNativeBuild\cmake\debug\x86 --target native-lib}
    [1/2] Building CXX object CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o
    [2/2] Linking CXX shared library ..\..\..\..\build\intermediates\cmake\debug\obj\x86\libnative-lib.so
    FAILED: cmd.exe /C "cd . && C:\Users\me\AppData\Local\Android\Sdk\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe  --target=i686-none-linux-android --gcc-toolchain=C:/Users/me/AppData/Local/Android/Sdk/ndk-bundle/toolchains/x86-4.9/prebuilt/windows-x86_64 --sysroot=C:/Users/me/AppData/Local/Android/Sdk/ndk-bundle/sysroot -fPIC -isystem C:/Users/me/AppData/Local/Android/Sdk/ndk-bundle/sysroot/usr/include/i686-linux-android -D__ANDROID_API__=21 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -mstackrealign -Wa,--noexecstack -Wformat -Werror=format-security   -O0 -fno-limit-debug-info  -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a --sysroot C:/Users/me/AppData/Local/Android/Sdk/ndk-bundle/platforms/android-21/arch-x86 -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libnative-lib.so -o ..\..\..\..\build\intermediates\cmake\debug\obj\x86\libnative-lib.so CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o  C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_highgui.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_features2d.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_shape.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_imgcodecs.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_ml.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_videoio.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_dnn.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_flann.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_objdetect.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_core.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_calib3d.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_video.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_superres.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_photo.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_imgproc.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_stitching.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_videostab.a -llog C:/OpenCV-android-sdk/sdk/native/3rdparty/libs/x86/liblibprotobuf.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_calib3d.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_features2d.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_highgui.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_videoio.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_imgcodecs.a C:/OpenCV-android-sdk/sdk/native/3rdparty/libs/x86/liblibjpeg.a C:/OpenCV-android-sdk/sdk/native/3rdparty/libs/x86/liblibwebp.a C:/OpenCV-android-sdk/sdk/native/3rdparty/libs/x86/liblibpng.a C:/OpenCV-android-sdk/sdk/native/3rdparty/libs/x86/liblibtiff.a C:/OpenCV-android-sdk/sdk/native/3rdparty/libs/x86/liblibjasper.a C:/OpenCV-android-sdk/sdk/native/3rdparty/libs/x86/libIlmImf.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_flann.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_video.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_photo.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_imgproc.a C:/OpenCV-android-sdk/sdk/native/staticlibs/x86/libopencv_core.a -lz C:/OpenCV-android-sdk/sdk/native/3rdparty/libs/x86/libcpufeatures.a C:/OpenCV-android-sdk/sdk/native/3rdparty/libs/x86/libittnotify.a -llog C:/OpenCV-android-sdk/sdk/native/3rdparty/libs/x86/libtbb.a -lc -ldl -lm C:/OpenCV-android-sdk/sdk/native/3rdparty/libs/x86/libippiw.a C:/OpenCV-android-sdk/sdk/native/3rdparty/libs/x86/libippicv.a -latomic -lm "C:/Users/me/AppData/Local/Android/Sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/libs/x86/libgnustl_static.a" && cd ."
    C:/Users/me/AppData/Local/Android/Sdk/ndk-bundle/toolchains/x86-4.9/prebuilt/windows-x86_64/lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin\ld: error: C:/OpenCV-android-sdk/sdk/native/3rdparty/libs/x86/libippicv.a(jmp_icvippiNorm_L1_32f_C1R_as.s.o): relocation R_386_GOTOFF against preemptible symbol icv_ippJumpIndexForMergedLibs cannot be used when making a shared object
    C:/Users/me/AppData/Local/Android/Sdk/ndk-bundle/toolchains/x86-4.9/prebuilt/windows-x86_64/lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin\ld: error: C:/OpenCV-android-sdk/sdk/native/3rdparty/libs/x86/libippicv.a(jmp_icvippiCopyConstBorder_8u_C4IR_L_as.s.o): relocation R_386_GOTOFF against preemptible symbol icv_ippJumpIndexForMergedLibs cannot be used when making a shared object
    ................
    omitted similar error
    ................
    C:/Users/me/AppData/Local/Android/Sdk/ndk-bundle/toolchains/x86-4.9/prebuilt/windows-x86_64/lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin\ld: error: C:/OpenCV-android-sdk/sdk/native/3rdparty/libs/x86/libippicv.a(jmp_icvippiCopy_8u_C4MR_as.s.o): relocation R_386_GOTOFF against preemptible symbol icv_ippJumpIndexForMergedLibs cannot be used when making a shared object
    C:/Users/me/AppData/Local/Android/Sdk/ndk-bundle/toolchains/x86-4.9/prebuilt/windows-x86_64/lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin\ld: error: C:/OpenCV-android-sdk/sdk/native/3rdparty/libs/x86/libippicv.a(jmp_icvippiMirror_32f_C4IR_as.s.o): relocation R_386_GOTOFF against preemptible symbol icv_ippJumpIndexForMergedLibs cannot be used when making a shared object
    clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation)
    ninja: build stopped: subcommand failed.
    

    error message

1 个答案:

答案 0 :(得分:1)

正在OpenCV GitHub上跟踪此问题: OpenCV doesn't link on Android x86/x86_64 with ndk 16.0.4442984 with R_386_GOTOFF error (已关闭)。

TL; NR: OpenCV-android-sdk 的预建二进制文件,特别是 x86 / libippicv.a ,与最新的NDK R16 即可。最简单的解决方法是使用older NDK version。如果你不能,那么排除 libippicv.a patch应该可以胜任:

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