OpenCV与Gradle在Android NDK中的本地集成

OpenCV native integration in Android NDK with Gradle

本文关键字:集成 NDK Gradle Android OpenCV      更新时间:2023-10-16

我正在尝试使用C++中的一些代码,这些代码在android项目中使用openCV库。我使用的是Android studio 2.1和Gradle 2.1.0版本(实验版0.7.0)。问题是编译器找不到opencv库。例如,在此代码中:

#include <string.h>
#include <jni.h>
#include <opencv2/opencv.hpp>
extern "C" {
JNIEXPORT void JNICALL
 Java_com_teaminfernale_gazetracker_MainActivity_filterImage(JNIEnv *env, jobject instance,
                                                        jlong matAddr) {
    cv::Mat& src_img  = *(cv::Mat*)matAddr;
    cv::cvtColor( src_img, src_img, CV_BGR2GRAY );
}

这就是错误:

Error:(12) undefined reference to `cv::cvtColor(cv::_InputArray const&, cv::_OutputArray const&, int, int)'
Error:error: ld returned 1 exit status
Error:Execution failed for task ':app:linkMain-jniArm64-v8aDebugAllSharedLibrary'.
A build operation failed.
Linker failed while linking libmain-jni.so.

这里是我的等级文件:

built.gradle在应用程序文件夹中:

apply plugin: 'com.android.model.application'
model {
android {
    compileSdkVersion = 23
    buildToolsVersion = "23.0.2"
    defaultConfig.with {
        applicationId = "com.teaminfernale.gazetracker"
        minSdkVersion.apiLevel = 19
        targetSdkVersion.apiLevel = 23
        versionCode = 1
        versionName = "1.0"
    }
    buildTypes {
        release {
            minifyEnabled = false
            proguardFiles.add(file('proguard-android.txt'))
        }
    }
    ndk {
        moduleName = "main-jni"
        cppFlags.add("-std=c++11")
        cppFlags.add("-fexceptions")
        cppFlags.add("-I${file("src/main/jni/include")}".toString())
        ldLibs.add("android")
        ldLibs.add("EGL")
        ldLibs.add("GLESv2")
        ldLibs.add("dl")
        ldLibs.add("log")
        ldLibs.add("z")
        stl = "gnustl_shared"
    }

}
android.productFlavors {
    create("arm") {
        ndk.with {
            abiFilters.add("armeabi")
            File curDir = file('./')
            curDir = file(curDir.absolutePath)
            String libsDir = curDir.absolutePath+"\src\main\jniLibs\armeabi\"
            ldFlags.add(libsDir + "libopencv_core.a")
            ldFlags.add(libsDir + "libIlmImf.a")
            ldFlags.add(libsDir + "liblibjasper.a")
            ldFlags.add(libsDir + "liblibjpeg.a")
            ldFlags.add(libsDir + "liblibpng.a")
            ldFlags.add(libsDir + "liblibtiff.a")
            ldFlags.add(libsDir + "liblibwebp.a")
            ldFlags.add(libsDir + "libtbb.a")
            ldFlags.add(libsDir + "libopencv_calib3d.a")
            ldFlags.add(libsDir + "libopencv_features2d.a")
            ldFlags.add(libsDir + "libopencv_flann.a")
            ldFlags.add(libsDir + "libopencv_hal.a")
            ldFlags.add(libsDir + "libopencv_highgui.a")
            ldFlags.add(libsDir + "libopencv_imgcodecs.a")
            ldFlags.add(libsDir + "libopencv_imgproc.a")
            ldFlags.add(libsDir + "libopencv_ml.a")
            ldFlags.add(libsDir + "libopencv_objdetect.a")
            ldFlags.add(libsDir + "libopencv_photo.a")
            ldFlags.add(libsDir + "libopencv_shape.a")
            ldFlags.add(libsDir + "libopencv_stitching.a")
            ldFlags.add(libsDir + "libopencv_superres.a")
            ldFlags.add(libsDir + "libopencv_ts.a")
            ldFlags.add(libsDir + "libopencv_video.a")
            ldFlags.add(libsDir + "libopencv_videoio.a")
            ldFlags.add(libsDir + "libopencv_videostab.a")
            ldFlags.add(libsDir + "libopencv_java3.so")
        }
    }
    create("arm7") {
        ndk.with {
            abiFilters.add("armeabi-v7a")
            File curDir = file('./')
            curDir = file(curDir.absolutePath)
            String libsDir = curDir.absolutePath+"\src\main\jniLibs\armeabi-v7a\"
            ldFlags.add(libsDir + "libopencv_core.a")
            ldFlags.add(libsDir + "libIlmImf.a")
            ldFlags.add(libsDir + "liblibjasper.a")
            ldFlags.add(libsDir + "liblibjpeg.a")
            ldFlags.add(libsDir + "liblibpng.a")
            ldFlags.add(libsDir + "liblibtiff.a")
            ldFlags.add(libsDir + "liblibwebp.a")
            ldFlags.add(libsDir + "libtbb.a")
            ldFlags.add(libsDir + "libopencv_calib3d.a")
            ldFlags.add(libsDir + "libopencv_features2d.a")
            ldFlags.add(libsDir + "libopencv_flann.a")
            ldFlags.add(libsDir + "libopencv_hal.a")
            ldFlags.add(libsDir + "libopencv_highgui.a")
            ldFlags.add(libsDir + "libopencv_imgcodecs.a")
            ldFlags.add(libsDir + "libopencv_imgproc.a")
            ldFlags.add(libsDir + "libopencv_ml.a")
            ldFlags.add(libsDir + "libopencv_objdetect.a")
            ldFlags.add(libsDir + "libopencv_photo.a")
            ldFlags.add(libsDir + "libopencv_shape.a")
            ldFlags.add(libsDir + "libopencv_stitching.a")
            ldFlags.add(libsDir + "libopencv_superres.a")
            ldFlags.add(libsDir + "libopencv_ts.a")
            ldFlags.add(libsDir + "libopencv_video.a")
            ldFlags.add(libsDir + "libopencv_videoio.a")
            ldFlags.add(libsDir + "libopencv_videostab.a")
            ldFlags.add(libsDir + "libopencv_java3.so")
        }
    }
    create("arm8") {
        ndk.with {
            abiFilters.add("arm64-v8a")
            File curDir = file('./')
            curDir = file(curDir.absolutePath)
            String libsDir = curDir.absolutePath+"\src\main\jniLibs\arm64-v8a\"
            ldFlags.add(libsDir + "libopencv_core.a")
            ldFlags.add(libsDir + "libIlmImf.a")
            ldFlags.add(libsDir + "liblibjasper.a")
            ldFlags.add(libsDir + "liblibjpeg.a")
            ldFlags.add(libsDir + "liblibpng.a")
            ldFlags.add(libsDir + "liblibtiff.a")
            ldFlags.add(libsDir + "liblibwebp.a")
            ldFlags.add(libsDir + "libtbb.a")
            ldFlags.add(libsDir + "libopencv_calib3d.a")
            ldFlags.add(libsDir + "libopencv_features2d.a")
            ldFlags.add(libsDir + "libopencv_flann.a")
            ldFlags.add(libsDir + "libopencv_hal.a")
            ldFlags.add(libsDir + "libopencv_highgui.a")
            ldFlags.add(libsDir + "libopencv_imgcodecs.a")
            ldFlags.add(libsDir + "libopencv_imgproc.a")
            ldFlags.add(libsDir + "libopencv_ml.a")
            ldFlags.add(libsDir + "libopencv_objdetect.a")
            ldFlags.add(libsDir + "libopencv_photo.a")
            ldFlags.add(libsDir + "libopencv_shape.a")
            ldFlags.add(libsDir + "libopencv_stitching.a")
            ldFlags.add(libsDir + "libopencv_superres.a")
            ldFlags.add(libsDir + "libopencv_ts.a")
            ldFlags.add(libsDir + "libopencv_video.a")
            ldFlags.add(libsDir + "libopencv_videoio.a")
            ldFlags.add(libsDir + "libopencv_videostab.a")
            ldFlags.add(libsDir + "libopencv_java3.so")
        }
    }
    create("x86") {
        ndk.with {
            abiFilters.add("x86")
            File curDir = file('./')
            curDir = file(curDir.absolutePath)
            String libsDir = curDir.absolutePath+"\src\main\jniLibs\x86\"
            ldFlags.add(libsDir + "libopencv_core.a")
            ldFlags.add(libsDir + "libIlmImf.a")
            ldFlags.add(libsDir + "liblibjasper.a")
            ldFlags.add(libsDir + "liblibjpeg.a")
            ldFlags.add(libsDir + "liblibpng.a")
            ldFlags.add(libsDir + "liblibtiff.a")
            ldFlags.add(libsDir + "liblibwebp.a")
            ldFlags.add(libsDir + "libtbb.a")
            ldFlags.add(libsDir + "libopencv_calib3d.a")
            ldFlags.add(libsDir + "libopencv_features2d.a")
            ldFlags.add(libsDir + "libopencv_flann.a")
            ldFlags.add(libsDir + "libopencv_hal.a")
            ldFlags.add(libsDir + "libopencv_highgui.a")
            ldFlags.add(libsDir + "libopencv_imgcodecs.a")
            ldFlags.add(libsDir + "libopencv_imgproc.a")
            ldFlags.add(libsDir + "libopencv_ml.a")
            ldFlags.add(libsDir + "libopencv_objdetect.a")
            ldFlags.add(libsDir + "libopencv_photo.a")
            ldFlags.add(libsDir + "libopencv_shape.a")
            ldFlags.add(libsDir + "libopencv_stitching.a")
            ldFlags.add(libsDir + "libopencv_superres.a")
            ldFlags.add(libsDir + "libopencv_ts.a")
            ldFlags.add(libsDir + "libopencv_video.a")
            ldFlags.add(libsDir + "libopencv_videoio.a")
            ldFlags.add(libsDir + "libopencv_videostab.a")
            ldFlags.add(libsDir + "libopencv_java3.so")
        }
    }
    create("x86-64") {
        ndk.with {
            abiFilters.add("x86_64")
            File curDir = file('./')
            curDir = file(curDir.absolutePath)
            String libsDir = curDir.absolutePath+"\src\main\jniLibs\x86_64\"
            ldFlags.add(libsDir + "libopencv_core.a")
            ldFlags.add(libsDir + "libIlmImf.a")
            ldFlags.add(libsDir + "liblibjasper.a")
            ldFlags.add(libsDir + "liblibjpeg.a")
            ldFlags.add(libsDir + "liblibpng.a")
            ldFlags.add(libsDir + "liblibtiff.a")
            ldFlags.add(libsDir + "liblibwebp.a")
            ldFlags.add(libsDir + "libtbb.a")
            ldFlags.add(libsDir + "libopencv_calib3d.a")
            ldFlags.add(libsDir + "libopencv_features2d.a")
            ldFlags.add(libsDir + "libopencv_flann.a")
            ldFlags.add(libsDir + "libopencv_hal.a")
            ldFlags.add(libsDir + "libopencv_highgui.a")
            ldFlags.add(libsDir + "libopencv_imgcodecs.a")
            ldFlags.add(libsDir + "libopencv_imgproc.a")
            ldFlags.add(libsDir + "libopencv_ml.a")
            ldFlags.add(libsDir + "libopencv_objdetect.a")
            ldFlags.add(libsDir + "libopencv_photo.a")
            ldFlags.add(libsDir + "libopencv_shape.a")
            ldFlags.add(libsDir + "libopencv_stitching.a")
            ldFlags.add(libsDir + "libopencv_superres.a")
            ldFlags.add(libsDir + "libopencv_ts.a")
            ldFlags.add(libsDir + "libopencv_video.a")
            ldFlags.add(libsDir + "libopencv_videoio.a")
            ldFlags.add(libsDir + "libopencv_videostab.a")
            ldFlags.add(libsDir + "libopencv_java3.so")
        }
    }
    create("mips") {
        ndk.with {
            abiFilters.add("mips")
            File curDir = file('./')
            curDir = file(curDir.absolutePath)
            String libsDir = curDir.absolutePath+"\src\main\jniLibs\mips\"
            ldFlags.add(libsDir + "libopencv_core.a")
            ldFlags.add(libsDir + "libIlmImf.a")
            ldFlags.add(libsDir + "liblibjasper.a")
            ldFlags.add(libsDir + "liblibjpeg.a")
            ldFlags.add(libsDir + "liblibpng.a")
            ldFlags.add(libsDir + "liblibtiff.a")
            ldFlags.add(libsDir + "liblibwebp.a")
            ldFlags.add(libsDir + "libtbb.a")
            ldFlags.add(libsDir + "libopencv_calib3d.a")
            ldFlags.add(libsDir + "libopencv_features2d.a")
            ldFlags.add(libsDir + "libopencv_flann.a")
            ldFlags.add(libsDir + "libopencv_hal.a")
            ldFlags.add(libsDir + "libopencv_highgui.a")
            ldFlags.add(libsDir + "libopencv_imgcodecs.a")
            ldFlags.add(libsDir + "libopencv_imgproc.a")
            ldFlags.add(libsDir + "libopencv_ml.a")
            ldFlags.add(libsDir + "libopencv_objdetect.a")
            ldFlags.add(libsDir + "libopencv_photo.a")
            ldFlags.add(libsDir + "libopencv_shape.a")
            ldFlags.add(libsDir + "libopencv_stitching.a")
            ldFlags.add(libsDir + "libopencv_superres.a")
            ldFlags.add(libsDir + "libopencv_ts.a")
            ldFlags.add(libsDir + "libopencv_video.a")
            ldFlags.add(libsDir + "libopencv_videoio.a")
            ldFlags.add(libsDir + "libopencv_videostab.a")
            ldFlags.add(libsDir + "libopencv_java3.so")
        }
    }
    create("mips-64") {
        ndk.with {
            abiFilters.add("mips64")
            File curDir = file('./')
            curDir = file(curDir.absolutePath)
            String libsDir = curDir.absolutePath+"\src\main\jniLibs\mips64\"
            ldFlags.add(libsDir + "libopencv_core.a")
            ldFlags.add(libsDir + "libIlmImf.a")
            ldFlags.add(libsDir + "liblibjasper.a")
            ldFlags.add(libsDir + "liblibjpeg.a")
            ldFlags.add(libsDir + "liblibpng.a")
            ldFlags.add(libsDir + "liblibtiff.a")
            ldFlags.add(libsDir + "liblibwebp.a")
            ldFlags.add(libsDir + "libtbb.a")
            ldFlags.add(libsDir + "libopencv_calib3d.a")
            ldFlags.add(libsDir + "libopencv_features2d.a")
            ldFlags.add(libsDir + "libopencv_flann.a")
            ldFlags.add(libsDir + "libopencv_hal.a")
            ldFlags.add(libsDir + "libopencv_highgui.a")
            ldFlags.add(libsDir + "libopencv_imgcodecs.a")
            ldFlags.add(libsDir + "libopencv_imgproc.a")
            ldFlags.add(libsDir + "libopencv_ml.a")
            ldFlags.add(libsDir + "libopencv_objdetect.a")
            ldFlags.add(libsDir + "libopencv_photo.a")
            ldFlags.add(libsDir + "libopencv_shape.a")
            ldFlags.add(libsDir + "libopencv_stitching.a")
            ldFlags.add(libsDir + "libopencv_superres.a")
            ldFlags.add(libsDir + "libopencv_ts.a")
            ldFlags.add(libsDir + "libopencv_video.a")
            ldFlags.add(libsDir + "libopencv_videoio.a")
            ldFlags.add(libsDir + "libopencv_videostab.a")
            ldFlags.add(libsDir + "libopencv_java3.so")
        }
    }
    create("all")
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.3.0'
compile project(':opencv')
}

opencv文件夹中的built.gradle:

apply plugin: 'com.android.library'
buildscript {
repositories {
    mavenCentral()
}
dependencies {
    classpath 'com.android.tools.build:gradle:2.1.0'
}
}
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
    minSdkVersion 19
    targetSdkVersion 23
    versionCode 2480
    versionName "2.4.8"
}
sourceSets {
    main {
        manifest.srcFile 'AndroidManifest.xml'
        java.srcDirs = ['src']
        resources.srcDirs = ['src']
        res.srcDirs = ['res']
        aidl.srcDirs = ['src']
        jniLibs.srcDir 'src/main/jniLibs'
    }
}
}

主项目文件夹中的built.gradle:

buildscript {
repositories {
    jcenter()
}
dependencies {
    classpath 'com.android.tools.build:gradle-experimental:0.7.0'
}
}
allprojects {
repositories {
    jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

settings.grade:

include ':app'
include ':opencv'

这里的完整项目如果可以更清楚:https://github.com/eug93/GazeTracker

很抱歉我的无能,但我没能找到任何可行的解决方案。感谢

您需要在jni文件夹中添加android.mk文件

以及build.gradle 中的以下行

sourceSets.main{

    jni.srcDirs = [] //disable automatic ndk-build call
    jniLibs.srcDir 'src/main/jniLibs'
}
buildTypes {
..
    }