Build native OpenCV 4 for use with Qt 5 on Android
This tutorial explains how to use OpenCV 4 on Android with C++ and the Qt 5 framework. 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 already installed with all 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.
Start by verifying that you can build and run a Qt application on your Android device. When that is working, continue with this tutorial.
Download and extract OpenCV sources
wget https://github.com/opencv/opencv/archive/4.1.1.tar.gz tar xf 4.1.1.tar.gz
Prepare building OpenCV
cd opencv-4.1.1 mkdir build cd build
Configure the build
How you configure OpenCV for building depends on the target Qt version (5.11 or older, 5.12 or later) and Android target, 32-bit or 64-bit. For older Qt versions you need to use a Android NDK that still supports gcc, for 5.12 and later you need to use NDK with clang. The following shows configuration examples for various combinations. Remember to adjust SDK paths to suit or installation.
Configure OpenCV build for 32-bit, Qt 5.11 or older
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.
~/Android/Sdk/cmake/3.6.4111459/bin/cmake .. \ -DANDROID_ABI="armeabi-v7a with NEON" -DANDROID_NATIVE_API_LEVEL=23 -DANDROID_TOOLCHAIN=gcc \ -DCMAKE_TOOLCHAIN_FILE=/home/xxx/Android/Sdk/ndk-bundle/build/cmake/android.toolchain.cmake \ -DANDROID_NDK=/home/xxx/Android/Sdk/ndk-bundle \ -DANDROID_SDK=/home/xxx/Android/Sdk -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release \ -DBUILD_ANDROID_PROJECTS=OFF -DANDROID_STL=gnustl_static \ -DWITH_OPENCL=ON -DWITH_TBB=ON -DENABLE_NEON=ON -DANDROID_ARM_NEON=ON -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF
This will configure the OpenCV build for building Android native shared libraries for the armv7 with NEON platform, using gcc and gnustl.
Configure OpenCV build for 64-bit, for Qt 5.12 and later
If you are using Qt 5.12 or later version, you can now build 64-bit Android apps. In this case you need to build 64-bit native libraries of OpenCV.
~/Android/Sdk/cmake/3.6.4111459/bin/cmake .. \ -DANDROID_ABI=arm64-v8a -DANDROID_NATIVE_API_LEVEL=23 \ -DANDROID_ARM_NEON=ON -DANDROID_TOOLCHAIN=clang \ -DCMAKE_TOOLCHAIN_FILE=/home/xxx/Android/Sdk/ndk-bundle/build/cmake/android.toolchain.cmake \ -DANDROID_NDK=/home/xxx/Android/Sdk/ndk-bundle \ -DANDROID_SDK=/home/xxx/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
Build and install OpenCV
As we are only interested in a native library we skip building of android 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.
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.
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.1.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 }
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.1.1/build-armv8/install/sdk/native/jni/include LIBS += -L$$PWD/3rdparty/opencv-armv8/ -ltbb -lopencv_core -lopencv_imgproc -lopencv_dnn }
Thats it
That should be it.
Next Tutorial will show how to use OpenCV with Qt. Stay tuned.