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

标签 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 编辑成这个


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

最佳答案

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 .如果不能,patch排除 libippicv.a 应该做的工作:

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

关于android - 如何在 Android Studio 3.1.2 中添加原生 OpenCV?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50189368/

相关文章:

opencv - 无法分割 RGB channel

android - 如何在 Phonegap 3.4.0 上以编程方式退出应用程序?

c++ - org-mode 导出 html 时无法高亮 C++ 源代码

ubuntu - 在 Ubuntu 上安装 OpenCV-2.4.3 时出错

c++ - 压入 STL 堆栈是通过引用传递的,但是堆栈是否复制了值?

c++ - 大写字母输入不能在 cpp 程序中工作

python cv2.VideoCapture 打不开

java - Android Studio - 任务 ':app:compileDebugJavaWithJavac' 执行失败

android - URL 方案在 Android 浏览器中不起作用

android - RecyclerView 带有隐藏/显示他们的 child 的项目