Adding OpenCV to Native C code through CMake on Android Studio
UPDATE 21-Oct-19: Deprecated Git/Simpler Way in favor of new AndroidOpenCVGradlePlugin
UPDATE 22-May-18: Added missing step number 6.
UPDATE 10-May-17: New solution provides proper integration of OpenCV into application with CMake and Android Gradle plugin 2.3.1. Tested using Android Studio 2.3.1.
UPDATE 11-May-17: An additional solution has been provided
There are two ways of including OpenCV.
Using AndroidOpenCVGradlePlugin
Visit https://github.com/ahasbini/AndroidOpenCVGradlePlugin for more details.
Git/Simpler Way
Visit https://github.com/ahasbini/Android-OpenCV for more details.
Manual/Advanced Way
To include OpenCV libraries into Android Studio Project, its best to create a new Library Module in the project and port the files from OpenCV Android SDK bundle into it:
- Create a new module by selecting File>New Module.
- Select "Android Library", and then enter the details:
- Library name:
OpenCV
- Module name:
opencv
- Package name:
org.opencv
- Library name:
- Once the new module created, copy the contents of
path_to_opencv_sdk/sdk/java/src
directory intopath_to_your_project/opencv/src/main/java
. - Under
main
, create the following directly path:aidl/org/opencv/engine
and movemain/java/org/opencv/engine/OpenCVEngineInterface.aidl
into it. - Copy the contents of
path_to_opencv_sdk/sdk/java/res
intopath_to_your_project/opencv/src/main/res
. - Create
sdk
folder insidepath_to_your_project/opencv/src/
and copypath_to_opencv_sdk/sdk/native
folder into it. - Within the
opencv
module, createCMakeLists.txt
file and add the following lines in the following order:
cmake_minimum_required(VERSION 3.4.1)
set(OpenCV_DIR "src/sdk/native/jni")
find_package(OpenCV REQUIRED)
message(STATUS "OpenCV libraries: ${OpenCV_LIBS}")
include_directories(${OpenCV_INCLUDE_DIRS})
- Within the
opencv
module, edit thebuild.gradle
file as such:
...
android {
...
defaultConfig {
minSdkVersion 8
targetSdkVersion 25
versionCode 3200
versionName "3.2.0"
...
externalNativeBuild {
cmake {
cppFlags "-frtti -fexceptions"
}
}
}
buildTypes {
...
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
sourceSets {
main {
jni.srcDirs = [jni.srcDirs, 'src/sdk/native/jni/include']
jniLibs.srcDirs = [jniLibs.srcDirs, 'src/sdk/native/3rdparty/libs', 'src/sdk/native/libs']
}
}
}
...
- Within the
app
(application module, could be another name) module, create/editCMakeLists.txt
file and add the following lines in the following order (Note the different path set toOpenCV_DIR
):
set(OpenCV_DIR "../opencv/src/sdk/native/jni")
find_package(OpenCV REQUIRED)
message(STATUS "OpenCV libraries: ${OpenCV_LIBS}")
target_link_libraries(YOUR_TARGET_LIB ${OpenCV_LIBS})
- Within the
app
(application module, could be another name) module, edit thebuild.gradle
file as such:
...
android {
...
defaultConfig {
...
externalNativeBuild {
cmake {
cppFlags "-frtti -fexceptions"
}
}
buildTypes {
...
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
dependencies {
...
compile project(':opencv')
}
- Do a gradle sync, and now the OpenCV native libs, header files and Java wrapper classes are included.
When project is built and apk is launched, you could inspect the packaged apk under path_to_project/path_to_app_module/build/output/
(drag the apk onto the text editor tabs of Android Studio)
You should see a libopencv_java3.so
under each abi architecture folder.
Initialize the OpenCV SDK in your java class :
public class MyClass {
static {
if (BuildConfig.DEBUG) {
OpenCVLoader.initDebug();
}
}
...
}
And you should see within logcat messages specifying the OpenCV has been loaded (the first error is normal):
05-10 10:42:31.451 D/OpenCV/StaticHelper: Trying to get library list
05-10 10:42:31.452 E/OpenCV/StaticHelper: OpenCV error: Cannot load info library for OpenCV
05-10 10:42:31.452 D/OpenCV/StaticHelper: Library list: ""
05-10 10:42:31.452 D/OpenCV/StaticHelper: First attempt to load libs
05-10 10:42:31.452 D/OpenCV/StaticHelper: Trying to init OpenCV libs
05-10 10:42:31.452 D/OpenCV/StaticHelper: Trying to load library opencv_java3
05-10 10:42:32.031 D/OpenCV/StaticHelper: Library opencv_java3 loaded
05-10 10:42:32.031 D/OpenCV/StaticHelper: First attempt to load libs is OK
05-10 10:42:32.045 I/OpenCV/StaticHelper: General configuration for OpenCV 3.2.0 =====================================
05-10 10:42:32.045 I/OpenCV/StaticHelper: Version control: 3.2.0
05-10 10:42:32.045 I/OpenCV/StaticHelper: Platform:
05-10 10:42:32.045 I/OpenCV/StaticHelper: Timestamp: 2016-12-23T13:04:49Z
05-10 10:42:32.045 I/OpenCV/StaticHelper: Host: Linux 4.8.0-25-generic x86_64
05-10 10:42:32.045 I/OpenCV/StaticHelper: Target: Linux 1 x86_64
05-10 10:42:32.045 I/OpenCV/StaticHelper: CMake: 2.8.12.2
05-10 10:42:32.045 I/OpenCV/StaticHelper: CMake generator: Ninja
05-10 10:42:32.045 I/OpenCV/StaticHelper: CMake build tool: /usr/bin/ninja
05-10 10:42:32.045 I/OpenCV/StaticHelper: Configuration: Release
05-10 10:42:32.045 I/OpenCV/StaticHelper: C/C++:
05-10 10:42:32.045 I/OpenCV/StaticHelper: Built as dynamic libs?: NO
05-10 10:42:32.045 I/OpenCV/StaticHelper: C++ Compiler: /usr/bin/ccache /opt/android/android-ndk-r10e/toolchains/x86_64-4.9/prebuilt/linux-x86_64/bin/x86_64-linux-android-g++ (ver 4.9)
How to compile and share two c++ libraries on an android build using CMake
the error you get is telling you that it cannot find opencv include file:
#include <opencv2/core.hpp>
you need to locate the opencv2 folder, and pass it to cmake as an additional include directory:
https://cmake.org/cmake/help/v3.0/command/include_directories.html
example: Adding OpenCV to Native C code through CMake on Android Studio
cmake_minimum_required(VERSION 3.4.1)
set(OpenCV_DIR "src/sdk/native/jni")
find_package(OpenCV REQUIRED)
message(STATUS "OpenCV libraries: ${OpenCV_LIBS}")
include_directories(${OpenCV_INCLUDE_DIRS})
or you can use this approach:
https://github.com/ahasbini/Android-OpenCV/blob/master/app/CMakeLists.txt
How to add native OpenCV in Android Studio 3.1.2?
This problem is being tracked on OpenCV GitHub: OpenCV doesn't link on Android x86/x86_64 with ndk 16.0.4442984 with R_386_GOTOFF error (closed).
TL;NR: the prebuilt binaries of OpenCV-android-sdk, and in particular the x86/libippicv.a, is not compatible with the latest NDK r16. The easiest workaround is to use an older NDK version. If you cannot, the patch which excludes libippicv.a should do the job:
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs,libippicv.a -Wl,--exclude-libs,libippiw.a")
CMake error while adding opencv 4.5.2 into my android studio project
The key is "not" to rename the sdk folder. It is because OpenCV hardcoded the path with the name of “sdk” in the native/jni/OpenCVConfig.cmake.
How can I integrate OpenCV 4.0 into a pure C++ Android NDK project?
Download opencv Android package (e.g. opencv-4.0.1-android-sdk) and unpack to, say,
~/android
.To the bottom of CMakeLists.txt, add
set( OpenCV_DIR "~/android/OpenCV-android-sdk/sdk/native/jni" )
find_package( OpenCV REQUIRED )
target_link_libraries(game opencv_java)
The package will define the following variables:
OpenCV_LIBS : The list of all imported targets for OpenCV modules.
OpenCV_INCLUDE_DIRS : The list of OpenCV include directories. With CMake >= 2.8.11 you don't even need to write
include_directories(${OpenCV_INCLUDE_DIRS})
This version of prebuilt OpenCV SDK defines also
OpenCV_VERSION : The version of this OpenCV build: "4.0.1"
OpenCV_ANDROID_NATIVE_API_LEVEL : Minimum required level of Android API: "16".
This means that your app manifest needs minSdkVersion 16 or higher (the original sample needs a fix here).
Instead of the shared library that contains all OpenCV functionality, you can use static libraries (opencv_imgcodecs, opencv_stitching, et al). These static libraries assume the default ANDROID_STL=c++_static.
For best results, use NDK r.18 or r.19.
UPDATE: NDK r.21 works well for opencv 4.3.0.
Related Topics
Android Persistence Room: "Cannot Figure Out How to Read This Field from a Cursor"
Understanding Recyclerview Sethasfixedsize
Recyclerview Changing Items During Scroll
Jni and Gradle in Android Studio
Why Do I Want to Avoid Non-Default Constructors in Fragments
How to Display a List of Images in a Listview in Android
How to Hide a Button Programmatically
How to Center Icon and Text in a Android Button with Width Set to "Fill Parent"
Can't Include C++ Headers Like Vector in Android Ndk
How to Add a Fast-Scroller to the Recyclerview
Adb Install Fails with Install_Failed_Test_Only
How to Add New Column to Android SQLite Database
How to Attach the Android Support Library Source in Eclipse
Write Android Logcat Data to a File
Android + Pair Devices via Bluetooth Programmatically
How to Change Background Color in Android App
Programmatically Change Input Type of the Edittext from Password to Normal & Vice Versa
Android: Remove All the Previous Activities from the Back Stack