草庐IT

Android Studio 链接 OpenCV 静态库

coder 2023-12-20 原文

目前,我正在从事一个使用 OpenCV3 进行实时视频处理(应用一组滤色器)的项目,我设法让它与 Java 一起工作,没有任何问题。

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

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

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我在github上找到的例子。 现在,我在尝试这样做时发现的问题之一是 OPENCV 有几个静态库文件,因此 post说,我必须将每个添加到 gradle 的不同库中才能链接它们,所以这就是为什么我的 gradle 文件中充满了重复的库定义。

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

#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));
    }
}
}

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

最佳答案

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

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 静态库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34701003/

有关Android Studio 链接 OpenCV 静态库的更多相关文章

  1. ruby-on-rails - Ruby url 到 html 链接转换 - 2

    我正在使用Rails构建一个简单的聊天应用程序。当用户输入url时,我希望将其输出为html链接(即“url”)。我想知道在Ruby中是否有任何库或众所周知的方法可以做到这一点。如果没有,我有一些不错的正则表达式示例代码可以使用... 最佳答案 查看auto_linkRails提供的辅助方法。这会将所有URL和电子邮件地址变成可点击的链接(htmlanchor标记)。这是文档中的代码示例。auto_link("Gotohttp://www.rubyonrails.organdsayhellotodavid@loudthinking.

  2. ruby-on-rails - Prawn - 表格单元格内的链接 - 2

    我正在尝试用Prawn生成PDF。在我的PDF模板中,我有带单元格的表格。在其中一个单元格中,我有一个电子邮件地址:cell_email=pdf.make_cell(:content=>booking.user_email,:border_width=>0)我想让电子邮件链接到“mailto”链接。我知道我可以这样链接:pdf.formatted_text([{:text=>booking.user_email,:link=>"mailto:#{booking.user_email}"}])但是将这两行组合起来(将格式化文本作为内容)不起作用:cell_email=pdf.make_c

  3. Vscode+Cmake配置并运行opencv环境(Windows和Ubuntu大同小异) - 2

    之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m

  4. ruby - 使用 Watir 检查错误链接 - 2

    我有一个未排序的链接列表,我将其保存在旁边,我想单击每个链接并确保它转到真实页面而不是404、500等。问题是我不知道该怎么做。是否有一些我可以检查的对象会给我http状态代码或任何东西?mylinks=Browser.ul(:id,'my_ul_id').linksmylinks.eachdo|link|link.click#needtocheckfora200statusorsomethinghere!how?Browser.backend 最佳答案 我的回答与铁皮人的想法类似。require'net/http'require'

  5. ruby - 如何为 pbcopy 生成富文本链接 - 2

    我一直在玩一个脚本,它在Chrome中获取选定的文本并在Google中查找它,提供四个最佳选择,然后粘贴相关链接。它以不同的格式粘贴,具体取决于当前在Chrome中打开的页面-DokuWiki打开的DokuWiki格式,普通网站的HTML,我想要我的WordPress所见即所得编辑器的富文本。我尝试使用pbpaste-Preferrtf来查看没有其他样式的富文本链接在粘贴板上的样子,但它仍然输出纯文本。在文本编辑中保存文件并进行试验后,我想出了以下内容text=%q|{\rtf1{\field{\*\fldinst{HYPERLINK"URL"}}{\fldrsltTEXT}}}|te

  6. ruby-on-rails - 如何从按钮或链接单击的 View 调用 Rails 方法 - 2

    基本上,我试图在用户单击链接(或按钮或某种类型的交互元素)时执行Rails方法。我试着把它放在View中:但这似乎没有用。它最终只是在用户甚至没有点击“添加”链接的情况下调用该函数。我也用link_to试过了,但也没用。我开始认为没有一种干净的方法可以做到这一点。无论如何,感谢您的帮助。附言。我在ApplicationController中定义了该方法,它是一个辅助方法。 最佳答案 View和Controller是相互独立的。为了使链接在Controller内执行函数调用,您需要对应用程序中的端点执行ajax调用。该路由应调用rub

  7. ruby - 在 Mechanize 中使用 JavaScript 单击链接 - 2

    我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan

  8. ruby - 使用指向 ruby​​ 可执行文件的符号链接(symbolic link)时查找相关库 - 2

    假设您有一个可执行文件foo.rb,其库bar.rb的布局如下:/bin/foo.rb/lib/bar.rb在foo.rb的header中放置以下要求以在bar.rb中引入功能:requireFile.dirname(__FILE__)+"../lib/bar.rb"只要对foo.rb的所有调用都是直接的,这就可以正常工作。如果你把$HOME/project和符号链接(symboliclink)foo.rb放入$HOME/usr/bin,然后__FILE__解析为$HOME/usr/bin/foo.rb,因此无法找到bar.rb关于foo.rb的目录名.我意识到像ruby​​gems这

  9. ruby-on-rails -/usr/local/lib/libz.1.dylib,文件是为 i386 构建的,它不是被链接的体系结构 (x86_64) - 2

    在我的mac上安装几个东西时遇到这个问题,我认为这个问题来自将我的豹子升级到雪豹。我认为这个问题也与macports有关。/usr/local/lib/libz.1.dylib,filewasbuiltfori386whichisnotthearchitecturebeinglinked(x86_64)有什么想法吗?更新更具体地说,这发生在安装nokogirigem时日志看起来像:xslt_stylesheet.c:127:warning:passingargument1of‘Nokogiri_wrap_xml_document’withdifferentwidthduetoproto

  10. ruby - 使用 Nokogiri 和 Ruby 从 html 文档获取链接和 href 文本? - 2

    我正在尝试使用nokogirigem提取页面上的所有url及其链接文本,并将链接文本和url存储在散列中。FooBar我想回去{"Foo"=>"#foo","Bar"=>"#bar"} 最佳答案 这是一个单行:Hash[doc.xpath('//a[@href]').map{|link|[link.text.strip,link["href"]]}]#=>{"Foo"=>"#foo","Bar"=>"#bar"}拆分一点可以说更具可读性:h={}doc.xpath('//a[@href]').eachdo|link|h[link.t

随机推荐