c++ – How to integrate OpenCV into Qt Creator Android project-ThrowExceptions

Exception or error:

I use Qt Creator to compile an Android application. I needed to integrate OpenCV into it, and it took me half a day to configure it properly, so I want to document the steps I took here, in case somebody else ever has to do it.

How to solve:

Edit: For OpenCV 4.x see the answers below. My answer was tested on OpenCV 2.4 only.

Original answer:


First, I downloaded OpenCV-2.4.10-android-sdk, and put into my project directory. It contains static libraries, and link order matters for static libraries for GCC. So you need to order them just so. This is how my .pro file looked in the end ($$_PRO_FILE_PWD_ refers to the project directory):

INCLUDEPATH += "$$_PRO_FILE_PWD_/OpenCV-2.4.10-android-sdk/sdk/native/jni/include"
android {
    LIBS += \
        -L"$$_PRO_FILE_PWD_/OpenCV-2.4.10-android-sdk/sdk/native/3rdparty/libs/armeabi-v7a"\
        -L"$$_PRO_FILE_PWD_/OpenCV-2.4.10-android-sdk/sdk/native/libs/armeabi-v7a"\
        -llibtiff\
        -llibjpeg\
        -llibjasper\
        -llibpng\
        -lIlmImf\
        -ltbb\
        -lopencv_core\
        -lopencv_androidcamera\
        -lopencv_flann\
        -lopencv_imgproc\
        -lopencv_highgui\
        -lopencv_features2d\
        -lopencv_calib3d\
        -lopencv_ml\
        -lopencv_objdetect\
        -lopencv_video\
        -lopencv_contrib\
        -lopencv_photo\
        -lopencv_java\
        -lopencv_legacy\
        -lopencv_ocl\
        -lopencv_stitching\
        -lopencv_superres\
        -lopencv_ts\
        -lopencv_videostab

    ANDROID_PACKAGE_SOURCE_DIR=$$_PRO_FILE_PWD_/android
}

After that the project will compile but it will fail to run with the error

E/AndroidRuntime(11873): java.lang.UnsatisfiedLinkError: Cannot load library: link_image[1891]:   176 could not load needed library 'libopencv_java.so' for 'libMyProject.so' (load_library[1093]: Library 'libopencv_java.so' not found)

To overcome this, you need to add libopencv_java.so to your APK, and then manually load it from QtActivity.java. That’s what the ANDROID_PACKAGE_SOURCE_DIR=$$_PRO_FILE_PWD_/android line at the end was for. Now you need to place libopencv_java.so here:

project_root/android/libs/armeabi-v7a/libopencv_java.so
project_root/android/src/org/qtproject/qt5/android/bindings/QtActivity.java

You can get QtActivity.java from the Android target build directory, in my case the full path was c:\Workspace\build-MyProject-Android_for_armeabi_v7a_GCC_4_9_Qt_5_4_0-Debug\android-build\src\org\qtproject\qt5\android\bindings\QtActivity.java, and just copy it.

Then you find those lines in it:

        // now load the application library so it's accessible from this class loader
        if (libName != null)
            System.loadLibrary(libName);

And load libopencv_java.so before them, so they become:

        // This is needed for OpenCV!!!
        System.loadLibrary("opencv_java");

        // now load the application library so it's accessible from this class loader
        if (libName != null)
            System.loadLibrary(libName);

Note that you pass opencv_java to System.loadLibrary(), even though the file is libopencv_java.so.


Edit: I forgot to mention, but I already had installed OpenCV Manager on my phone when trying to run one of the samples that come with OpenCV-2.4.10-android-sdk, so I don’t know if it’s needed or not. In any event, keep it in mind, if it fail even after my steps, you might need to download OpenCV Manager (it’s available on the Google Store).

Edit 2: I’m using adt-bundle-windows-x86-20140702, android-ndk-r10d, OpenCV-2.4.10-android-sdk, Qt Creator 3.3.0, and my build target is “Android for armeabi-v7a (GCC 4.9, Qt 5.4.0)”.

Edit 3: From Daniel Saner’s comment:

In OpenCV 3.x, opencv_java has been renamed to opencv_java3. Also, while I didn’t look into the specific changes that might have effected this, the workaround regarding that library in the final step seems to no longer be necessary. The app compiles and runs without the ANDROID_PACKAGE_SOURCE_DIR line

Edit 4: @myk’s comment:

Worked for me with OpenCV 3.2. To workaround the build issues with carotene finish the LIBS+ section with: -lopencv_videostab\ -ltegra_hal\ – myk 2 hours ago

###

For OpenCV 4, sashoalm’s approach did not work for me until I adapted it:

  1. Download the Android-Pack and unzip it somewhere. We’ll create a qmake-variable OPENCV_ANDROID which points to that directory later.
  2. Add the following snippet to your *.pro-file:

    android {
        contains(ANDROID_TARGET_ARCH,arm64-v8a) {
            isEmpty(OPENCV_ANDROID) {
                error("Let OPENCV_ANDROID point to the opencv-android-sdk, recommended: v4.0")
            }
            INCLUDEPATH += "$$OPENCV_ANDROID/sdk/native/jni/include"
            LIBS += \
                -L"$$OPENCV_ANDROID/sdk/native/libs/arm64-v8a" \
                -L"$$OPENCV_ANDROID/sdk/native/3rdparty/libs/arm64-v8a" \
                -llibtiff \
                -llibjpeg-turbo \
                -llibjasper \
                -llibpng \
                -lIlmImf \
                -ltbb \
                -lopencv_java4 \
    
            ANDROID_EXTRA_LIBS = $$OPENCV_ANDROID/sdk/native/libs/arm64-v8a/libopencv_java4.so
        } else {
            error("Unsupported architecture: $$ANDROID_TARGET_ARCH")
        }
    }
    

    This will work for the arm64-v8a only. If you happen to build for another architecture (apparently 32-Bit is still the default for Qt@Android), you must change the .../libs/arm64-v8a part of the paths (occurs 3 times) and the same to match your actual target-architecture (the contains(...)-part in the second line of the snippet).

  3. Tell qmake where to find the SDK. Add the following to qmake-call: "OPENCV_ANDROID=/path/to/OpenCV-android-sdk".
    • e.g., this looks like qmake example.pro "OPENCV_ANDROID=/home/user/OpenCV-android-sdk" from command line.
    • when you use QtCreator, add "OPENCV_ANDROID=..." to the “Additional arguments”-field. You can find it after enabling the Project-Mode in the Build-section of the android-kit. Expand the qmake-field under Build Steps

###

Starting from Android android-ndk-r18b, with Qt Creator 4.9.x kits, I could not use the openCV-4.1.1 pre-compiled shared libraries (.so) with Qt Android ABI armeabi-v7a target and ABI arm64-v8a, as Opencv standard is based on GCC, While the NDK-r18b removed gcc and uses clang compiler. ( I am getting

Fatal signal 11 (SIGSEGV), code 1

On initialize calling android_getCpuFeatures() when the application starts)
Thus, openCV shared libs must be compiled from sources for clang in order to be used with Qt Android kits.

This reference Compiling OpenCV on Android from C++ (Without OpenCVManager) was of real help. I would leave a reference here as well for a simple procedure I used under windows 10, to get opencv compiled with NDK 18 (clang) for Qt Android:

  • Downloaded openCV source code
  • Downloaded openCV contrib source for selected openCV version
  • Used cmake for windows
  • in the unzipped opencv source folder, created a new build folder.
  • MinGW from Qt installation can generally be used for building, So I used Qt 5.11.x (MinGW 5.3.0 32 bit) command line tool from Qt menu.
  • from command line, in new build folder, I could generate cmake configuration :

     C:\opencv-4.1.1\build> "C:\program files\cmake\bin\cmake" .. -G"MinGW Makefiles"
    -DBUILD_SHARED_LIBS=ON 
    -DANDROID_STL=c++_shared 
    -DANDROID_ABI="armeabi-v7a with NEON" 
    -DANDROID_NATIVE_API_LEVEL=23 
    -DANDROID_TOOLCHAIN=clang 
    -DCMAKE_TOOLCHAIN_FILE=D:\Qt\android-ndk-r18b\build\cmake\android.toolchain.cmake 
    -DANDROID_NDK=D:\Qt\android-ndk-r18b 
    -DANDROID_SDK=C:\Users\moham\AppData\Local\Android\sdk 
    -DCMAKE_BUILD_TYPE=Debug 
    -DBUILD_ANDROID_PROJECTS=OFF 
    -DWITH_OPENCL=ON -DWITH_TBB=ON -DENABLE_NEON=ON 
    -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF 
    -DBUILD_FAT_JAVA_LIB=OFF 
    
  • Then , C:\opencv-4.1.1\build>\mingw32-make -jx and C:\opencv-4.1.1\build>\mingw32-make install
  • the result libs can be picked from opencv-4.1.1\build\install folder
  • Link in Qt Android project:

    android {
           #opencv
           OPENCVLIBS = $$PWD/../opencv-4.1.1\build\install/sdk/native
           INCLUDEPATH = $$OPENCVLIBS/jni/include
           contains(ANDROID_TARGET_ARCH,armeabi-v7a) {
           # might need libs to be copied into app's library folder and loaded on start-up, in case android ships older libs??!
           ANDROID_EXTRA_LIBS = \
           $$OPENCVLIBS/libs/armeabi-v7a/libopencv_core.so \
           $$OPENCVLIBS/libs/armeabi-v7a/libopencv_imgproc.so \
           $$OPENCVLIBS/libs/armeabi-v7a/libtbb.so
           LIBS += -L"$$OPENCVLIBS/libs/armeabi-v7a"\
            -lopencv_core -lopencv_imgproc -ltbb
          }
    ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
    }
    
  • Also, copy the libs to ANDROID_PACKAGE_SOURCE_DIR

Note: If detailed control over cmake configuration is needed, cmake windows gui can be used, while not a must and not tested. AmMIN’s procedure is helpful for cmake tool, remember to add flag for shared Android STL.

Leave a Reply

Your email address will not be published. Required fields are marked *