【问题标题】:OpenCV - undefined reference to 'cv::CascadeClassifier::detectMultiScale()' after NDK updateOpenCV - NDK 更新后对 'cv::CascadeClassifier::detectMultiScale()' 的未定义引用
【发布时间】:2018-10-23 05:37:40
【问题描述】:

昨天我将包含 NDK 的 Android Studio 更新到版本 17.0.4754217,从那时起我就无法再运行我的应用程序了。当我尝试在更新后重新运行代码时,它给了我错误ABIs [mips64, armeabi, mips] are not supported for platform. Supported ABIs are [armeabi-v7a, arm64-v8a, x86, x86_64],所以我将它们从我的app.gradle 文件中的项目中排除,方法如下:abiFilters 'x86', 'x86_64', /*'armeabi',*/ 'armeabi-v7a', 'arm64-v8a'/*, 'mips', 'mips64'*/

但是,从那时起,我在使用 OpenCV 函数 cv::CascadeClassifier::detectMultiScale 的 C++ 文件中遇到了问题。

总是显示错误:CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o: In function detectAndDisplay(cv::Mat, double, int, std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >, cv::CascadeClassifier&)': D:\Schule\OpenCV\ARcpp\app\src\main\cpp/native-lib.cpp:158: undefined reference to cv::CascadeClassifier::detectMultiScale(cv::_InputArray const&, std::__ndk1::vector<cv::Rect_<int>, std::__ndk1::allocator<cv::Rect_<int> > >&, double, int, int, cv::Size_<int>, cv::Size_<int>)'.

我这样调用函数:cascadeClassifier.detectMultiScale(frame_gray, sights, scaleFactor, minNeighbours, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));。其余代码与 OpenCV 教程 https://docs.opencv.org/2.4/doc/tutorials/objdetect/cascade_classifier/cascade_classifier.html 中显示的非常相似。

除了 NDK,我还使用 CMake 和 LLDB,我包含的 OpenCV 库是 openCVLibrary320。同样,在我下载提到的 NDK 更新之前,所有这些都有效。

在构建或执行应用程序时总是出现的其余错误是:Build command failed. Error while executing process C:\Users\chris\AppData\Local\Android\Sdk\cmake\3.6.4111459\bin\cmake.exe with arguments {--build D:\Schule\OpenCV\ARcpp\app\.externalNativeBuild\cmake\debug\arm64-v8a --target native-lib} [1/1] Linking CXX shared library ..\..\..\..\build\intermediates\cmake\debug\obj\arm64-v8a\libnative-lib.so FAILED: cmd.exe /C "cd . && C:\Users\chris\AppData\Local\Android\Sdk\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=aarch64-none-linux-android --gcc-toolchain=C:/Users/chris/AppData/Local/Android/Sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64 --sysroot=C:/Users/chris/AppData/Local/Android/Sdk/ndk-bundle/sysroot -fPIC -isystem C:/Users/chris/AppData/Local/Android/Sdk/ndk-bundle/sysroot/usr/include/aarch64-linux-android -D__ANDROID_API__=21 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -Wa,--noexecstack -Wformat -Werror=format-security -std=c++11 -std=c++11 -frtti -fexceptions -O0 -fno-limit-debug-info -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a -nostdlib++ --sysroot C:/Users/chris/AppData/Local/Android/Sdk/ndk-bundle/platforms/android-21/arch-arm64 -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -LC:/Users/chris/AppData/Local/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/arm64-v8a -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\arm64-v8a\libnative-lib.so CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o -llog ../../../../src/main/jniLibs/arm64-v8a/libopencv_java3.so -latomic -lm "C:/Users/chris/AppData/Local/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_static.a" "C:/Users/chris/AppData/Local/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++abi.a" && cd ." clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation) ninja: build stopped: subcommand failed.

我真的很迷茫,希望有人知道答案。

【问题讨论】:

  • 我在使用最新版本 3.4.2 for android 时也遇到了同样的错误。无法使用 'gnustl_static' 作为参数,因为 ndk 现在不支持它。需要帮助!

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


【解决方案1】:

OpenCV 是用ANDROID_STL=gnustl_static 构建的。升级后,您的 NDK 会改用默认的 libc++。您可以在 app/build.gradle 中明确设置 ANDROID_STL:

android { defaultConfig { externalNativeBuild { cmake {
    arguments '-DANDROID_STL=gnustl_static'
} } } }

(参见示例here

【讨论】:

  • 'gnustl_static' 不再受支持。有什么解决办法吗?
  • @Sar:您可以使用c++_shared 重新构建 OpenCV,或者下载较旧的 NDK。
  • 我不知道如何使用 c++_shared 重建 OpenCV。如果您可以提供任何参考资料,这将很有帮助并感谢您的提示
【解决方案2】:

在将 opencv 与您的项目可执行文件链接时,您始终必须与通用库 -lopencv_core 链接。但是有些包需要额外的链接标志。例如, 如果你在

中使用 highgui
#include <opencv2/highgui/highgui.hpp>

您必须为 -lopencv_highgui 添加 opencv_highgui 链接标志。

在您的情况下,CascadeClassifiers 在

中定义
#include "opencv2/objdetect.hpp"

因此需要与 opencv_objdetect -lopencv_objdetect 的链接。

解决方法是在编译时添加链接标志-lopencv_objdetect

【讨论】:

  • 非常感谢您的回复,不幸的是我真的不知道如何在 Android Studio 中执行此操作。
  • 我刚刚注意到我的 C++ 代码中已经包含了 #include &lt;opencv2/objdetect/objdetect.hpp&gt;。这是你的意思吗?因为考虑到上述错误,添加/删除它没有任何区别。
【解决方案3】:

为所有寻求者提供更完整的答案。在您的项目中使用 OpenCV 预构建的静态库和原生组件。

这就是我为build.gradle 准备的:

defaultConfig {
    minSdkVersion 21
    targetSdkVersion 21
    externalNativeBuild {
        cmake {
            cppFlags "-fexceptions -std=gnu++11"
            arguments '-DANDROID_STL=gnustl_static'
        }
    }
    ndk {
        // Specifies the ABI configurations of your native
        // libraries Gradle should build and package with your APK.
        abiFilters 'armeabi-v7a', 'x86'
        stl = "gnustl_shared"
    }
}

这是 CMakeLists.txt:

set(OPENCV_LIBRARIES ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_NDK_ABI_NAME}/libopencv_video.a
                     ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_NDK_ABI_NAME}/libopencv_imgproc.a
                     ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_NDK_ABI_NAME}/libopencv_core.a
                     ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_NDK_ABI_NAME}/libopencv_highgui.a
                     ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_NDK_ABI_NAME}/libtbb.a
                     ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_NDK_ABI_NAME}/libcpufeatures.a
                     )

if (${ANDROID_ABI} STREQUAL "x86")
    set(OPENCV_LIBRARIES ${OPENCV_LIBRARIES}
                         ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_NDK_ABI_NAME}/libippiw.a
                         ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_NDK_ABI_NAME}/libippicv.a
                         ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_NDK_ABI_NAME}/libittnotify.a
                         )
    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs,libippicv.a -Wl,--exclude-libs,libippiw.a")
endif()

if (${ANDROID_ABI} STREQUAL "armeabi-v7a")
    set(OPENCV_LIBRARIES ${OPENCV_LIBRARIES}
                         ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_NDK_ABI_NAME}/libtegra_hal.a
                         )
endif()

(然后将${OPENCV_LIBRARIES} 用作您的target_link_libraries

【讨论】:

    【解决方案4】:

    对此link 的第一条评论可以为您节省很多时间,我将其复制到下面:

    “我有类似的问题。结果你必须使用与用于构建 OpenCV Android SDK 的类似的 Android NDK,如果版本 ~3.4 是 Android NDK 10。最近,OpenCV Android SDK 4.0。 1 已发布,它适用于最新的 NDK 版本(当时为 19)。”

    在发布这篇文章时,您可以找到发布版4.1.2。您可以查看link 是否有最新版本。

    选择最新版本后,在本例中为 4.1.2,下载文件 opencv-4.1.2-android-sdk.zip,解压缩并将 sdk/native 文件夹复制到 yourprojectfolder/your-app/src/sdk/。

    你准备好了。

    【讨论】:

      【解决方案5】:

      我通过将this OpenCV + contrib lib (opencv4_1_0_contrib) 和official Java OpenCV 类 (4.3) 混合使用解决了这个问题。在 Android 9 上成功运行官方 OpenCV FaceDetection 示例。


      一些有用的代码:

      应用级 build.gradle:

      android{defaultConfig{
      //...
      externalNativeBuild {
                  cmake {
                      cppFlags "-frtti -fexceptions"
                      abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
                      //I import OpenCV as module and provide it path to CMake
                      arguments "-DOpenCV_DIR=/" + rootProject.projectDir.path + "/sdk/native"
                   }
              }
      }}
      
      externalNativeBuild {
              cmake {
                  path "src/main/cpp/CMakeLists.txt"
                  version "3.10.2"
              }
          }
      

      我的 CMakeLists.txt:

      # Sets the minimum version of CMake required to build the native library.
      cmake_minimum_required(VERSION 3.4.1)
      
      #Add OpenCV 4 lib
      include_directories(${OpenCV_DIR}/jni/include) #Path from gradle to OpenCV Cmake
      add_library( lib_opencv SHARED IMPORTED )
      set_target_properties(lib_opencv PROPERTIES IMPORTED_LOCATION ${OpenCV_DIR}/libs/${ANDROID_ABI}/libopencv_java4.so)
      
      #Add Your Native Lib
      add_library(native-lib SHARED native-lib.cpp)
      add_library(detection_based_tracker SHARED detectionbasedtracker_jni.cpp)
      
      #Add&Link Android Native Log lib with others libs
      find_library(log-lib log)
      target_link_libraries(detection_based_tracker lib_opencv ${log-lib})
      

      NDK 版本为 21.0.611669。 此外,我不使用 -DANDROID_STL=gnustl_static 之类的 CMake 参数。

      【讨论】:

        猜你喜欢
        • 2016-09-19
        • 2021-02-26
        • 2019-06-04
        • 2021-11-02
        • 1970-01-01
        • 2021-11-08
        • 2022-06-22
        • 1970-01-01
        • 2020-09-17
        相关资源
        最近更新 更多