Android OpenCV-对'的未定义引用;NDK更新后的cv::CascadeClassifier::detectMultiScale()

Android OpenCV-对'的未定义引用;NDK更新后的cv::CascadeClassifier::detectMultiScale(),android,c++,android-studio,opencv,android-ndk,Android,C++,Android Studio,Opencv,Android Ndk,昨天,我将我的Android Studio Include NDK更新为17.0.4754217版本,从那以后我再也不能运行我的应用程序了。当我尝试在更新后重新运行代码时,它给了我一个错误ABIs[mips64,armeabi,mips]不受平台支持。受支持的ABI是[armeabi-v7a、arm64-v8a、x86、x86_64]因此我在我的应用程序中将它们从项目中排除。gradle文件如下:ABI过滤器'x86','x86_64',/*'armeabi',*/'armeabi-v7a','

昨天,我将我的Android Studio Include NDK更新为17.0.4754217版本,从那以后我再也不能运行我的应用程序了。当我尝试在更新后重新运行代码时,它给了我一个错误
ABIs[mips64,armeabi,mips]不受平台支持。受支持的ABI是[armeabi-v7a、arm64-v8a、x86、x86_64]
因此我在我的
应用程序中将它们从项目中排除。gradle
文件如下:
ABI过滤器'x86','x86_64',/*'armeabi',*/'armeabi-v7a','arm64-v8a'/*,'mips',mips64'*/

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

它总是显示错误:
cmakfiles/native lib.dir/src/main/cpp/native lib.cpp.o:在函数detectAndDisplay中(cv::Mat,double,int,std::u ndk1::basic_string,cv::CascadeClassifier&):
D:\Schule\OpenCV\ARcpp\app\src\main\cpp/native lib.cpp:158:对cv::CascadeClassifier::detectMultiScale的未定义引用(cv:_inputarrayconst&,std:uu ndk1::vector&,double,int,int,cv::Size,cv::Size)。

我这样调用函数:
cascadescriter.detectMultiScale(frame_gray,sights,scaleFactor,minNeighbours,0 | CV_HAAR_SCALE_IMAGE,Size(30,30))。代码的其余部分与OpenCV教程中显示的非常相似

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

生成或执行应用程序时始终出现的其余错误是:
Build命令失败。
执行进程C:\Users\chris\AppData\Local\Android\Sdk\cmake\3.6.4111459\bin\cmake.exe时出错,参数为{--build D:\Schule\OpenCV\ARcpp\app\.externalNativeBuild\cmake\debug\arm64-v8a--target native lib}
[1/1]链接CXX共享库..\\..\build\mediates\cmake\debug\obj\arm64-v8a\libnative-lib.so
失败:cmd.exe/C"光碟,C:\Users\chris\AppData\Local\Android\Sdk\ndk bundle\toolschains\llvm\prebuild\windows-x86\u 64\bin\clang++.exe--target=aarch64 none-linux-Android--gcc toolschain=C:/Users/chris/AppData/Local/Android/Sdk/ndk bundle/toolschains/aarch64-linux-Android-4.9/prebuild/windows-x86\u 64--sysroot=C:/Users/ch64/chris/AppData/Local/Android/ndk bundle/sysroot-fPIC-isystem C:/Users/chris/AppData/Local/Android/Sdk/ndk bundle/sysroot/usr/include/aarch64 linux-Android-Dèu-Androidèu-APIèu=21-g-DANDROID-ffunction-sections-funwind tables-fstack-protector-strong-无规范前缀-Wa,--noexecstack-Wformat-Werror=format-security-std=C++=11-frti-feexceptions-O0-fno-limit-debug-Wl,--排除libs,libgcc.a-Wl,--排除libs,libatomic.a-nostlib++--sysroot C:/Users/chris/AppData/Local/Android/Sdk/ndk bundle/platforms/Android-21/arch-arm64-Wl,--build id-Wl,--warn shared textrel-Wl,--致命警告-LC:/Users/chris/AppData/Local/Android/Sdk/ndk bundle/sources/cxx stl/llvm libc++/libs/arm64-8a-Wl,--无未定义-vz,noexecstack-Qunused arguments-Wl,-z,relro-Wl,-z,now-shared-Wl,-soname,libnative-lib.so-o….\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ build\mediates\cmake\debug\obj\arm64-v8a\libnative-lib.so-CMakeFiles/native-lib/src/main/cpp/cpp.o-llog/../../../src/main/jnilibopencv java3.so-latomic-lm“C:/Users/chris/AppData/Local/Android/Sdk/ndk bundle/sources/cxx stl/llvm libc++/libs/arm64-v8a/libc++u static.a”“C:/Users/chris/AppData/Local/Android/Sdk/ndk bundle/sources/cxx stl/llvm libc++/libs/arm64-v8a/libc++.a”&&cd。”
clang++.exe:错误:链接器命令失败,退出代码为1(使用-v查看调用)
忍者:构建停止:子命令失败。


我真的迷路了,希望有人知道答案

使用项目可执行文件链接opencv时,始终必须链接通用库-lopencv\u core。但是有些包需要额外的链接标志。例如 如果在中使用highgui

#include <opencv2/highgui/highgui.hpp>
因此需要一个与opencv_objdetect-lopencv_objdetect的链接

解决方案是在编译时添加链接标志-lopencv\u objdetect

OpenCV是用。升级后,NDK使用默认的libc++。您可以在应用程序/build.gradle中显式设置ANDROID\u STL

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

(见一个例子)。

对于所有的搜索者来说,这是一个更完整的答案。在带有本机组件的项目中使用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()
# 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})
(然后使用
${OPENCV_LIBRARIES}
创建您的
目标链接_库

关于这一点的第一条评论可以为您节省很多时间,我将其复制到下面:

“我也有类似的问题。事实证明,您使用了与构建OpenCV Android SDK类似的Android NDK,在版本~3.4的情况下是Android NDK 10。最近,OpenCV Android SDK 4.0.1已经发布,它与最新的NDK版本(当时为19)配合使用。”

在撰写本文时,您可以找到发行版。您可以查看是否有最新版本

选择最新版本(本例为4.1.2)后,下载文件,解压缩并将sdk/native文件夹复制到yourprojectfolder/your app/src/sdk/


你准备好出发了

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


一些有用的代码: 应用程序级别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"
        }
    }
My 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()
# 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。
另外,我不使用CMake的参数,比如
-DANDROID\u STL=gnustl\u static

非常感谢您的回答,不幸的是,我真的不知道怎么做