OpenCV - undefined reference to 'cv::CascadeClassifier::detectMultiScale() after NDK update

后端 未结 5 1281

Yesterday I updated my Android Studio included NDK to version 17.0.4754217and since then I can\'t run my app anymore. When I tried to rerun the code after the u

相关标签:
5条回答
  • 2021-01-06 07:17

    A more complete answer for all the seekers out there. Using OpenCV prebuilt static libraries in your project with a native component.

    This is what I have for the 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"
        }
    }
    

    This is the 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()
    

    (then use ${OPENCV_LIBRARIES} for your target_link_libraries)

    0 讨论(0)
  • 2021-01-06 07:21

    OpenCV is built with ANDROID_STL=gnustl_static. After upgrade, your NDK uses the default libc++ instead. You can set ANDROID_STL explicitly in your app/build.gradle:

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

    (see an example here).

    0 讨论(0)
  • 2021-01-06 07:30

    I solved this problem by using mix with this OpenCV + contrib lib (opencv4_1_0_contrib) and official Java OpenCV classes (4.3). Successfully run official OpenCV FaceDetection example on Android 9.


    Some usefull code:

    App level 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:

    # 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 version was 21.0.611669. Also I don't use arguments for CMake like -DANDROID_STL=gnustl_static.

    0 讨论(0)
  • When linkin opencv with your project executables, you always have to link with the general library -lopencv_core. But some packages require additional link flags. For example, if you use highgui as in

    #include <opencv2/highgui/highgui.hpp>
    

    you must add opencv_highgui link flag for : -lopencv_highgui.

    In you case, CascadeClassifiers are defined in

    #include "opencv2/objdetect.hpp"
    

    and thus requires a link with opencv_objdetect -lopencv_objdetect.

    The solution is to add the link flag -lopencv_objdetect when compiling.

    0 讨论(0)
  • 2021-01-06 07:33

    The first comment on this link can save you many hours which I copy past below:

    "I had similar issue. In turned out that you got to use similar Android NDK as one that was used to build OpenCV Android SDK, that in case of versions ~3.4 is Android NDK 10. Recently, OpenCV Android SDK 4.0.1 have been released and it works with the newest NDK version (19 at the time)."

    At the time of this post, you can find the release 4.1.2. You can check if there's a latest release on this link.

    After you select your latest version, in this case 4.1.2, download the file opencv-4.1.2-android-sdk.zip, unzip it and copy the sdk/native folder to yourprojectfolder/your-app/src/sdk/.

    You're ready to roll.

    0 讨论(0)
提交回复
热议问题