Build native OpenCV 4 for use together with Qt 5.12 or later in Android environments

18/01/2021 - 11:05
Average: 5 (4 votes)

This tutorial explains how to build and setup OpenCV 4.5 for the Qt 5.12 or later C++ framework on Android. There are some quirks that needs to be dealt with so that the libraries are built correctly so that they work correctly with Qt 5.

The tutorial assumes that you have Qt 5.12 or later already installed with all the required Android SDK & NDK dependencies working already. If not, install Android SDK & NDK and Qt first. This tutorial will not go into specific details on that. The versions of the Android components that Qt requires will work well for building OpenCV. Start by verifying that you can build and run a Qt application on your Android device. When that is working, continue with this tutorial.

Software package versions assumed by this guide are:

  • cmake 3.10.2.4988404
  • ndk 21.3.6528147

Android SDK is assumed to be installed in you home directory at ~/Android if this is not the case for you then just adjust the path in the example commands below.

Preparing OpenCV sources for building

Download and extract OpenCV sources

 wget -O opencv-4.5.1tar.gz https://github.com/opencv/opencv/archive/4.5.1.tar.gz
 tar xf opencv-4.5.1.tar.gz

Optional, Download and extract OpenCV Extra modules

If you would like to use opencv components from the OpenCV Extra modules, then download and extract the parallel version release of opencv_contrib. You can skip this step if you don't intend to use these.

wget -O opencv_contrib-4.5.1.tar.gz https://github.com/opencv/opencv_contrib/archive/4.5.1.tar.gz
tar xf opencv_contrib-4.5.1.tar.gz

Prepare building OpenCV

Prepare a build directory for OpenCV by creating a directory  under the source tree, you can use pretty much any name you like, but a good one is build, or for example if you are building both 32-bit and 64-bit versions you might use build32 and build64.

 cd opencv-4.5.1
 mkdir build
 cd build

Configure the OpenCV build

How you configure OpenCV for building depends on the target Qt version, 5.12 or later and Android target, 32-bit or 64-bit. For Qt 5.12 and later you need to use NDK with clang. The following shows configuration examples for various combinations. Remember to adjust any SDK paths to suit your installation of the Android SDK and NDK below.

Configure OpenCV build for 32-bit, Qt 5.12 or later

Configure the OpenCV build with the following parameters to cmake, adjust any SDK paths and versions to wherever you have the Android SDK installed on your system.

This will configure OpenCV build for building Android native shared libraries for the armv7 (32-bit) with NEON platform.

~/Android/Sdk/cmake/3.10.2.4988404/bin/cmake .. \
-DANDROID_ABI="armeabi-v7a with NEON" \
-DANDROID_NATIVE_API_LEVEL=24 \
-DANDROID_ARM_NEON=ON \
-DANDROID_TOOLCHAIN=clang \
-DCMAKE_TOOLCHAIN_FILE=~/Android/Sdk/ndk/21.3.6528147/build/cmake/android.toolchain.cmake \
-DANDROID_NDK=~/Android/Sdk/ndk/21.3.6528147 \
-DANDROID_SDK=/Android/Sdk \
-DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release \
-DBUILD_ANDROID_PROJECTS=OFF -DWITH_OPENCL=ON \
-DWITH_TBB=ON -DENABLE_NEON=ON \
-DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF

Configure OpenCV build for 64-bit, for Qt 5.12 and later

This will configure OpenCV build for building Android native shared libraries for the armv8 (64-bit) platform.

~/Android/Sdk/cmake/3.10.2.4988404/bin/cmake .. \
-DANDROID_ABI=arm64-v8a \
-DANDROID_NATIVE_API_LEVEL=24 \
-DANDROID_ARM_NEON=ON \
-DANDROID_TOOLCHAIN=clang \
-DCMAKE_TOOLCHAIN_FILE=~/Android/Sdk/ndk/21.3.6528147/build/cmake/android.toolchain.cmake \
-DANDROID_NDK=~/Android/Sdk/ndk/21.3.6528147 \
-DANDROID_SDK=~/Android/Sdk \
-DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release \
-DBUILD_ANDROID_PROJECTS=OFF -DWITH_OPENCL=ON \
-DWITH_TBB=ON -DENABLE_NEON=ON \
-DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF

Optional, add OpenCV extra modules

If you downloaded the extra modules and would like to have them built, then add the following configuration option the above:

-DOPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-4.5.1/modules

Build and install OpenCV

As we are only interested in native libraries, we skip building of any android specific projects and also enable shared libraries. If all goes well you should now have the build configured and ready to go.

Just run make and the OpenCV should build for you:

 make -j4 && make install/strip/fast

The Android install target will not install anything to your system, instead it will make directory structure with headers and libraries under a install/sdk directory. From here you can then copy the libraries and headers to a suitable location.

Note: If you need debugging information in the libraries then install using the install target instead.

We are interested in the libraries and they can now be found in the install/sdk/native/libs/armeabi-v7a/ (32-bit) or install/sdk/native/libs/arm64-v8a/ (64-bit) directory, you can copy all of them or just the ones you need, to your Qt project.

I tend to use a directory structure like "project-root/3rdparty/opencv-armv7/" for architecture specific 3rd-party binary libraries.

Reference the libraries & headers from your Qt project file

Next you need to reference the Android ARM libraries for linking and packaging from your project.

Add a section with the following contents, adjusted for your needs. In my application I only needed a couple of libraries but depending on what features of OpenCV you are using you need to add more of them.

You also need add the INCLUDEPATH setting that points to the OpenCV C++ header files. Adjust any example paths as needed for you installation.

Project settings for 32-bit Android (armeabi-v7a)

contains(ANDROID_TARGET_ARCH,armeabi-v7a) {
    ANDROID_EXTRA_LIBS = \
        $$PWD/3rdparty/opencv-armv7/libopencv_core.so \
        $$PWD/3rdparty/opencv-armv7/libopencv_imgproc.so \
        $$PWD/3rdparty/opencv-armv7/libopencv_dnn.so \
        $$PWD/3rdparty/opencv-armv7/libtbb.so
    INCLUDEPATH = /opt/Android/opencv-4.5.1/build-armv7/install/sdk/native/jni/include
    # Order might be important it seems, linker in older droids (4.2) are dumb
    LIBS += -L$$PWD/3rdparty/opencv-armv7/ -ltbb -lopencv_core -lopencv_imgproc -lopencv_dnn
}

Project settings for 64-bit Android (arm64-v8a)

contains(ANDROID_TARGET_ARCH,arm64-v8a) {
    ANDROID_EXTRA_LIBS = \
        $$PWD/3rdparty/opencv-armv8/libopencv_core.so \
        $$PWD/3rdparty/opencv-armv8/libopencv_imgproc.so \
        $$PWD/3rdparty/opencv-armv8/libopencv_dnn.so \
        $$PWD/3rdparty/opencv-armv8/libtbb.so

    INCLUDEPATH = /opt/Android/opencv-4.5.1/build-armv8a/install/sdk/native/jni/include
    LIBS += -L$$PWD/3rdparty/opencv-armv8/ -ltbb -lopencv_core -lopencv_imgproc -lopencv_dnn
}

Thats it

That should be it. You should be able to use OpenCV for your Qt application Android builds now.

Next Tutorial will show how to use OpenCV with Qt. Stay tuned.

Issues

Keywords: 
Qt, Android, OpenCV, C++, Android NDK