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

查看:125
本文介绍了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文件基于我在github上找到的这个示例. 现在,我发现尝试这样做的问题之一是OPENCV具有几个静态库文件,因此

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 include在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天全站免登陆