Android Studio 链接 OpenCV 静态库 [英] Android Studio linking OpenCV static libraries

查看:83
本文介绍了Android Studio 链接 OpenCV 静态库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我正在开发一个项目,该项目使用 OpenCV3 进行实时视频处理(应用一组滤色器),并且我设法让它与 Java 一起使用,没有任何问题.

Currently I'm working on a project that uses OpenCV3 for realtime video processing (applying a set of color filters), and I managed to get the it to work with Java without any problem.

接下来我尝试做的是通过 NDK 将我所有的 Java 逻辑实现到 C++(为了提高性能).这样我就不需要将 MAT 对象来回转换为字节缓冲区,从而节省了几个周期.但我真的很难尝试使用 gradle 链接 .so、.a 静态库和头文件,以便在我的 .CPP 文件上使用.

What I try to do next is to implement all my Java logic to C++ through NDK (in order to improve performance). This way I won't need to convert MAT object to byte buffers back and fort, saving a couple of cycles. But I'm really stuck trying to link the .so, .a static libraries and headers files using gradle to be used on my .CPP files.

这是我正在使用的 gradle 文件:

This is the gradle file that I'm using:

apply plugin: 'com.android.model.application'

def opencvandroid_sdk_path = file(project(':opencvandroid').projectDir).absolutePath + "/src/main"

model {

    repositories {
        libs(PrebuiltLibraries) {
            opencv {
                headers.srcDir "${opencvandroid_sdk_path}/jni/include/opencv2"
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("${opencvandroid_sdk_path}/jniLibs/${targetPlatform.getName()}/libopencv_calib3d.a")
                }
            }

            opencv1 {
                headers.srcDir "${opencvandroid_sdk_path}/jni/include/opencv2"
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("${opencvandroid_sdk_path}/jniLibs/${targetPlatform.getName()}/libopencv_core.a")
                }
            }

            opencv2 {
                headers.srcDir "${opencvandroid_sdk_path}/jni/include/opencv2"
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("${opencvandroid_sdk_path}/jniLibs/${targetPlatform.getName()}/libopencv_features2d.a")
                }
            }

            opencv3 {
                headers.srcDir "${opencvandroid_sdk_path}/jni/include/opencv2"
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("${opencvandroid_sdk_path}/jniLibs/${targetPlatform.getName()}/libopencv_flann.a")
                }
            }

            opencv4 {
                headers.srcDir "${opencvandroid_sdk_path}/jni/include/opencv2"
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("${opencvandroid_sdk_path}/jniLibs/${targetPlatform.getName()}/libopencv_highgui.a")
                }
            }

            opencv5 {
                headers.srcDir "${opencvandroid_sdk_path}/jni/include/opencv2"
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("${opencvandroid_sdk_path}/jniLibs/${targetPlatform.getName()}/libopencv_imgcodecs.a")
                }
            }

            opencv6 {
                headers.srcDir "${opencvandroid_sdk_path}/jni/include/opencv2"
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("${opencvandroid_sdk_path}/jniLibs/${targetPlatform.getName()}/libopencv_imgproc.a")
                }
            }

            opencv7 {
                headers.srcDir "${opencvandroid_sdk_path}/jni/include/opencv2"
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("${opencvandroid_sdk_path}/jniLibs/${targetPlatform.getName()}/libopencv_ml.a")
                }
            }

            opencv8 {
                headers.srcDir "${opencvandroid_sdk_path}/jni/include/opencv2"
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("${opencvandroid_sdk_path}/jniLibs/${targetPlatform.getName()}/libopencv_objdetect.a")
                }
            }

            opencv9 {
                headers.srcDir "${opencvandroid_sdk_path}/jni/include/opencv2"
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("${opencvandroid_sdk_path}/jniLibs/${targetPlatform.getName()}/libopencv_photo.a")
                }
            }

            opencv10 {
                headers.srcDir "${opencvandroid_sdk_path}/jni/include/opencv2"
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("${opencvandroid_sdk_path}/jniLibs/${targetPlatform.getName()}/libopencv_shape.a")
                }
            }

            opencv11 {
                headers.srcDir "${opencvandroid_sdk_path}/jni/include/opencv2"
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("${opencvandroid_sdk_path}/jniLibs/${targetPlatform.getName()}/libopencv_stitching.a")
                }
            }

            opencv12 {
                headers.srcDir "${opencvandroid_sdk_path}/jni/include/opencv2"
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("${opencvandroid_sdk_path}/jniLibs/${targetPlatform.getName()}/libopencv_superres.a")
                }
            }

            opencv13 {
                headers.srcDir "${opencvandroid_sdk_path}/jni/include/opencv2"
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("${opencvandroid_sdk_path}/jniLibs/${targetPlatform.getName()}/libopencv_video.a")
                }
            }

            opencv14 {
                headers.srcDir "${opencvandroid_sdk_path}/jni/include/opencv2"
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("${opencvandroid_sdk_path}/jniLibs/${targetPlatform.getName()}/libopencv_videoio.a")
                }
            }

            opencv15 {
                headers.srcDir "${opencvandroid_sdk_path}/jni/include/opencv2"
                binaries.withType(StaticLibraryBinary) {
                    staticLibraryFile = file("${opencvandroid_sdk_path}/jniLibs/${targetPlatform.getName()}/libopencv_videostab.a")
                }
            }
        }
    }

    android {
        compileSdkVersion = 23
        buildToolsVersion = "23.0.2"

        defaultConfig.with {
            applicationId = "com.example"
            minSdkVersion.apiLevel = 16
            targetSdkVersion.apiLevel = 23
            versionCode = 1
            versionName = "1.0"
        }
    }

    /*
     * native build settings
     */
    android.ndk {
        moduleName = "hello-jni"
        /*
         * Other ndk flags configurable here are
         * cppFlags += "-fno-rtti"
         * cppFlags += "-fno-exceptions"
         * ldLibs    = ["android", "log"]
         * stl       = "system"
         */
        platformVersion = 16 //same as minSdkVersion.apiLevel for better compatibility

        /*def jniPath = opencvandroid_sdk_path + "jniLibs"
        cppFlags += "-I${file(jniPath)}".toString()
        file(jniPath).eachDirRecurse { dir ->
            cppFlags += "-I${file(dir)}".toString()
        }*/

        stl = "c++_static"
        ldLibs.addAll(["atomic", "log", "android"])
    }

    android.sources {
        main {
            jni {
                dependencies {
                    library "opencv1" linkage "static"
                    library "opencv2" linkage "static"
                    library "opencv3" linkage "static"
                    library "opencv4" linkage "static"
                    library "opencv5" linkage "static"
                    library "opencv6" linkage "static"
                    library "opencv7" linkage "static"
                    library "opencv8" linkage "static"
                    library "opencv9" linkage "static"
                    library "opencv10" linkage "static"
                    library "opencv11" linkage "static"
                    library "opencv12" linkage "static"
                    library "opencv13" linkage "static"
                    library "opencv14" linkage "static"
                    library "opencv15" linkage "static"
                }
            }
        }
    }

    android.buildTypes {
        release {
            minifyEnabled = false
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.android.support:design:23.1.1'
    compile project(':opencvandroid')
}

我的 gradle 文件基于 this 示例.现在,我发现尝试这样做的问题之一是 OPENCV 有几个静态库文件,因此 post 说,我必须将每个添加到 gradle 的不同库中才能链接它们,所以这就是为什么我的 gradle 文件充满了重复的库定义.

I'm basing my gradle file on this example that I found on github. Now, one of the issues that I discover trying to do so, is that OPENCV have a couple of static libraries files, so as this post says, I have to add each one on a different lib on gradle in order to link them, so that's why my gradle file is filled with repeating library definitions.

现在,当我尝试在我的 .CPP 代码中包含头文件时,Android Studio 找不到它们(甚至找不到要使用的命名空间).这是我的 CPP 代码:

Now when I'm trying to include the headers files on my .CPP code, Android Studio cannot find them (not even the namespace to use). This is my CPP code:

#include <jni.h>
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/features2d/features2d.hpp"
#include <vector>

using namespace std;
using namespace cv;

extern "C" {
JNIEXPORT void JNICALL Java_com_example_Tutorial2Activity_FindFeatures(JNIEnv*, jobject, jlong addrGray, jlong addrRgba);

JNIEXPORT void JNICALL Java_com_example_Tutorial2Activity_FindFeatures(JNIEnv*, jobject, jlong addrGray, jlong addrRgba)
{
    Mat& mGr  = *(Mat*)addrGray;
    Mat& mRgb = *(Mat*)addrRgba;
    vector<KeyPoint> v;

    Ptr<FeatureDetector> detector = FastFeatureDetector::create(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));
    }
}
}

为了正确链接它们,我是否遗漏了什么?

Am I missing something in order to link them correctly?

推荐答案

OpenCV 静态库之间存在依赖关系.因此,您需要以完全正确的顺序包含它们..a 和 .o 包含在 GCC 中是顺序相关的,具有依赖关系的文件必须在它们所依赖的文件之前包含:

There are dependencies between the OpenCV static libraries. So you need to include them in exactly the right order. .a and .o includes are order dependent in GCC, files that have dependencies must be included before the files they depend on:

CV_LIBS = \
    $(CV_LIB_FOLDER)/libopencv_calib3d.a \
    $(CV_LIB_FOLDER)/libopencv_highgui.a \
    $(CV_LIB_FOLDER)/libopencv_video.a \
    $(CV_LIB_FOLDER)/libopencv_objdetect.a \
    $(CV_LIB_FOLDER)/libopencv_imgproc.a \
    $(CV_LIB_FOLDER)/libopencv_imgcodecs.a \
    $(CV_LIB_FOLDER)/libopencv_core.a \
    $(CV_LIB_FOLDER)/libopencv_hal.a

这篇关于Android Studio 链接 OpenCV 静态库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆