?

Log in

Previous Entry | Next Entry

Setup native OpenCV for Android

Мы рассмотрим здесь только установку OpenCV для нативного прораммирования в C++, но прежде одно замечание: инженеры OpenCV подготовили почти полный port библиотеки на Java, куда входят не только интерфейсы, необходимые для взаимодействия с Android, но и полный wrapper всех классов и методов библиотеки. Таким образом, вы можете программировать OpenCV, оставаясь в Java, без единой строчки на C++. Основная причина, из-за которой вам может понадобиться нативное программирование - быстродействие. Я не имею точных цифр, но если речь идет об обработке в режиме реального времени, то не стоит их и искать: любой VM будет медленнее, чем нативный код. (Обычно Java-код в 2-3 раза медленнее чем тот же код на C++). Еще одна причина, по которой стоит выбрать нативный код состоит в переносимости. Ну, не писать же тоже самое под iOS сначала?
С другой стороны, обработка уже сделанных изображений, например, не предъявляет особых требований к быстродействию и может быть выполнена значительно проще в Java, без нативного кода.
Но если наш путь ведет в real time (через Android Stuodio и Gradle), можно начинать.
Во-первых, нам понадобится NDK. Поскольку мы уже занимались его знакомством с Gradle, приведем лишь центральную часть:

task buildNative(type: Exec, description: 'Compile JNI source via NDK') {
    def ndkDir = 'D:\\android-ndk-r10d'
    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
        println "Using NDK from $ndkDir"
        commandLine "$ndkDir\\ndk-build.cmd",
                '-C', file('src/main/jni').absolutePath,
                '-j', Runtime.runtime.availableProcessors()
    } else {
        commandLine "$ndkDir\\ndk-build",
                '-C', file('src/main/jni').absolutePath,
                '-j', Runtime.runtime.availableProcessors()
    }
}


tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn buildNative
}


и полезную добавку:




defaultConfig {
...



ndk {
    moduleName "fastcvUtils"
    abiFilters "armeabi" "armeabi-v7a"
    ldLibs "EGL", "GLESv3", "dl", "log"
}





Нам нужно всего-лишь добавить в Android.mk одну строчку в поддержу OpenCV.

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# OpenCV
include D:/OpenCV-android-sdk/sdk/native/jni/OpenCV.mk

LOCAL_MODULE    := fastcvUtils
LOCAL_SRC_FILES := jni_part.cpp
LOCAL_LDLIBS +=  -llog -ldl

include $(BUILD_SHARED_LIBRARY)





После этого includes доступны, библиотеки подключены. Осталось разве что не забыть о namespaces:

#include 
#include 
#include 
#include 
#include 

using namespace std;
using namespace cv;




И наконец, метод с использованием OpenCV - FastFeatureDetector:




extern "C" {

JNIEXPORT void JNICALL Java_com_maximum_fastride_CameraCVActivity_FindFeatures(JNIEnv*, jclass, jlong addrGray, jlong addrRgba);

JNIEXPORT void JNICALL Java_com_maximum_fastride_CameraCVActivity_FindFeatures(JNIEnv*, jclass, jlong addrGray, jlong addrRgba)
{
    DPRINTF("Inside FindFeatures");

    Mat& mGr  = *(Mat*)addrGray;
    Mat& mRgb = *(Mat*)addrRgba;
    vector v;

    FastFeatureDetector detector(50);
    detector.detect(mGr, v);
    for( unsigned int i = 0; i < v.size(); i++ )
    {
        const KeyPoint& kp = v[i];
        circle(mRgb, Point(kp.pt.x, kp.pt.y), 10, Scalar(255,0,0,255));
    }

    DPRINTF("Finished FindFeatures");
}
}