Import OpenCV

  • macOS 10.13.6
  • Android Studio 3.5
  • Android API level 29
  • NDK r20
  • CMake 3.10.2
  • OpenCV 4.1.1 for Android

Create empty native project

  • module build gradle
android {    
    defaultConfig {
        externalNativeBuild {
            cmake {
                cppFlags ""
                arguments "-DANDROID_STL=c++_shared" // The default is static library variant of libc++
            }
        }
    }

    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
            version "3.10.2"
        }
    }
}

C++ Library Support

CMake

Download OpenCV

  • copy include folder from /Downloads/OpenCV-android-sdk/sdk/native/jni to Android project's c++ source folder: src/main/cpp.
  • copy all library folder from /Downloads/OpenCV-android-sdk/sdk/native/libs/ to Android project's JNI forlder: src/main/jniLibs/.
.
├── jni
│   └── include
│       └── opencv2
├── libs
│   ├── arm64-v8a
│   │   └── libopencv_java4.so
│   ├── armeabi-v7a
│   │   └── libopencv_java4.so
│   ├── x86
│   │   └── libopencv_java4.so
│   └── x86_64
│       └── libopencv_java4.so
└── staticlibs
.
├── cpp
│   └── include
│       └── opencv2
├── java
│   └── com
│       └── opencv
├── jniLibs
│   ├── arm64-v8a
│   │   └── libopencv_java4.so
│   ├── armeabi-v7a
│   │   └── libopencv_java4.so
│   ├── x86
│   │   └── libopencv_java4.so
│   └── x86_64
│       └── libopencv_java4.so
└── res

OpenCV releases page

Using CMake to import library

cmake_minimum_required(VERSION 3.10.2)

set(libs ${CMAKE_SOURCE_DIR}/../jniLibs) // declare the variable libs
include_directories(${CMAKE_SOURCE_DIR}/include)

add_library(lib_opencv SHARED IMPORTED)
set_target_properties(lib_opencv PROPERTIES IMPORTED_LOCATION ${libs}/${ANDROID_ABI}/libopencv_java4.so)

add_library(native-lib SHARED native-lib.cpp)
find_library(log-lib log)

target_link_libraries(native-lib lib_opencv ${log-lib})

CMake variables document

Others

  • native-lib.cpp
#include <jni.h>
#include <string>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

extern "C" JNIEXPORT jintArray JNICALL
Java_com_opencv_MainActivity_gray(JNIEnv *env, jobject instance, jintArray buf, jint w, jint h) {
    jint *cbuf = env->GetIntArrayElements(buf, JNI_FALSE);
    if (cbuf == nullptr) {
        return nullptr;
    }

    Mat imgData(h, w, CV_8UC4, (unsigned char *) cbuf);

    uchar *ptr = imgData.ptr(0);
    for (int i = 0; i < w * h; i++) {
        // Y = 0.299*R + 0.587*G + 0.114*B
        // BGRA
        int grayScale = (int) (ptr[4 * i + 2] * 0.299 + ptr[4 * i + 1] * 0.587 + ptr[4 * i + 0] * 0.114);
        ptr[4 * i + 1] = static_cast<uchar>(grayScale);
        ptr[4 * i + 2] = static_cast<uchar>(grayScale);
        ptr[4 * i + 0] = static_cast<uchar>(grayScale);
    }

    int size = w * h;
    jintArray result = env->NewIntArray(size);
    env->SetIntArrayRegion(result, 0, size, cbuf);
    env->ReleaseIntArrayElements(buf, cbuf, 0);
    return result;
}
  • MainActivity.kt
package com.opencv

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.graphics.Bitmap
import android.graphics.drawable.BitmapDrawable
import android.view.View
import android.widget.ImageView
import androidx.core.content.ContextCompat

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val bitmap = (ContextCompat.getDrawable(this, R.drawable.image) as BitmapDrawable).bitmap
        val w = bitmap.width
        val h = bitmap.height
        val pix = IntArray(w * h)
        bitmap.getPixels(pix, 0, w, 0, 0, w, h)

        val resultPixes = gray(pix, w, h)
        val result = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565)
        result.setPixels(resultPixes, 0, w, 0, 0, w, h)

        val img = findViewById<View>(R.id.img2) as ImageView
        img.setImageBitmap(result)
    }

    external fun gray(buf: IntArray, w: Int, h: Int): IntArray

    companion object {
        init {
            System.loadLibrary("native-lib")
        }
    }
}

results matching ""

    No results matching ""