Java OpenCV Android-无法解析相应的JNI函数

Java OpenCV Android-无法解析相应的JNI函数,java,android,c++,opencv,android-ndk,Java,Android,C++,Opencv,Android Ndk,我正试图通过以下概述的教程,使用Opencv设置Android Studio: 我可以得到提供教程的人获得的结果,但在尝试实际使用Opencv的一些函数时,我遇到了一些麻烦 我可以加载Opencv库,但在尝试使用一些本机函数(如“Imgcodecs.imread”)时,我得到错误:“.lang.unsatifiedlinkerror:long org.Opencv.Imgcodecs.Imgcodecs.imread_1(java.lang.String)”未找到任何实现” 我相信我已经追踪到以

我正试图通过以下概述的教程,使用Opencv设置Android Studio:

我可以得到提供教程的人获得的结果,但在尝试实际使用Opencv的一些函数时,我遇到了一些麻烦

我可以加载Opencv库,但在尝试使用一些本机函数(如“Imgcodecs.imread”)时,我得到错误:“.lang.unsatifiedlinkerror:long org.Opencv.Imgcodecs.Imgcodecs.imread_1(java.lang.String)”未找到任何实现”

我相信我已经追踪到以下问题:

[![在此处输入图像描述][1][1]

<> Po>看起来Android平台无法检测出我猜的本地C++代码应该从JNILBS文件夹中获取,我现在在APP/SRC/Mmain?< /P> 我已尝试将Android Studio更新为最新的稳定版本,并修复了Android SDK和NDK的文件路径,因为空白明显会影响本机代码的运行。这个问题仍然存在


在过去的4个小时里,我一直在努力解决这个问题,任何帮助都将不胜感激

最终编辑:我制作了一个教程,解释如何安装Opencv for Android以及SIFT/SURF算法-

看来我已经通过使用以下文件结构和依赖项解决了我的问题。我不能肯定地说我是怎么做到的,但我相信如果你在这里复制我的结构,那么你的也应该可以

确保Android SDK或NDK的文件路径中没有空格。Android Studio警告说,在加载本机代码时,这可能会导致问题

将包含“*.so”文件的文件夹放入/YOUR_PROJECT_ROOT/libs(您可能需要手动创建此libs文件夹)。 所有其他在线解决方案都声称要将它们放到app/src/main/jniLibs中,但对我来说并不管用

为了包含openCVLibrary300,我使用File->New->Import module将其作为模块导入,并将源目录设置为..\OpenCV android sdk\sdk\java

确保应用程序和导入库中的build.gradle文件共享相同的min和max sdk版本等

用于测试的示例代码-

我上面发布的示例代码确保在使用Opencv方法之前加载库。它使用了iGCODES.IdRead()函数,它使用C++中的原生代码,以前给了我“.Lun.NosidFieldLink错误:没有为长org .opencv.imgCODES.IMPGCODES.IMPReDIG1(java .Lang.Script)”错误找到./P>>


我想我是最合适的人,在用Android Studio解决了ndk问题后,在苦苦挣扎了一周之后,就这个问题给你一个切实可行的答案。这意味着您已经解决了这个问题,但我可以提供更多关于如何设置您自己的本机文件的信息,以防您需要它

首先要知道的是,目前Android Studio仍然存在一些内部缺陷,Java源文件中的本机函数声明可能仍然会触发“无法解析…”消息。事实上,只要你所有的源代码都是正确的,并且编译正确,就不会有什么问题

如果项目中没有自己的本机文件(C++,C),只需将.a或.so本机库放在src/main/jniLibs文件夹中,就不必修改gradle文件中的任何内容。系统会自动为你做一切

如果您有自己的本机文件并将它们放在src/main/jni文件夹中,那么您必须创建自己的makefile并将它们也放在jni文件夹中。您还必须修改应用程序模块中的gradle文件

下面是我为opencv的人脸检测示例所做的工作,我从这篇精彩的文章()中获得了原始代码,这篇文章实际上是从另一个人的方法中修改的,以简化执行:

我的项目结构:

My makefiles(确保在makefile中有库的原始sdk供参考):

Android.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
OPENCV_LIB_TYPE:=SHARED
include /home/ng/Desktop/OpenCV-android-sdk/sdk/native/jni/OpenCV.mk

LOCAL_SRC_FILES  := DetectionBasedTracker_jni.cpp
LOCAL_C_INCLUDES += $(LOCAL_PATH)
LOCAL_LDLIBS     += -llog -ldl

LOCAL_MODULE     := detection_based_tracker

include $(BUILD_SHARED_LIBRARY)
Application.mk:

    APP_STL := gnustl_static
    APP_CPPFLAGS := -frtti -fexceptions
    APP_ABI := armeabi-v7a armeabi
    APP_PLATFORM := android-19
应用程序模块中的My gradle.build文件:

apply plugin: 'com.android.application'
android {
    compileSdkVersion 23
    buildToolsVersion "23.0.1"

    defaultConfig {
        applicationId "org.opencv.samples.facedetect"
        minSdkVersion 14
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }
    sourceSets.main.jni.srcDirs = []

    task ndkBuild(type: Exec, description: 'Compile JNI source via NDK') {
       // ndkDir = project.plugins.findPlugin('com.android.application').getNdkFolder()
        commandLine "$ndkDir/ndk-build",
                'NDK_PROJECT_PATH=build/intermediates/ndk',
                'NDK_LIBS_OUT=src/main/jniLibs',
                'APP_BUILD_SCRIPT=src/main/jni/Android.mk',
                'NDK_APPLICATION_MK=src/main/jni/Application.mk'
    }

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

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.0'
    compile project(':openCVLibrary300')
}
实际上,您不必更改其他gradle文件来编译项目的本机部分。 您还可以通过命令行编译本机源代码,并将.so文件放回jniLibs文件夹。这也行得通。
我希望这对你的问题有所帮助。

哪个Java文件在你的截图中显示了错误?@AlexCohn Imgcodecs.Java在openCVLibrary300/src/main/Java/org/opencv/imgcodecsI中会说-忽略这个错误,这是Android Studio无法理解本机库的唯一原因。但是我没有OpenCV的Java包装器的第一手经验。@AlexCohn不幸的是,我不能,因为当尝试使用Imgcodecs.imread()读取图像时,应用程序会因我在原始问题中发布的错误消息而崩溃。然后,您可能无法将OpenCV本机库打包到APK中。指定
model{android.sources{main.jniLibs.source{srcDirs+=“OpenCV_libs”}}}
并将缺少的库放在那里。我刚在本周末完成了本教程的设置:它工作了,但我注意到我的apk很大,因为它将所有本机二进制文件添加到apk中,所以几乎是40兆字节。我在考虑是否可以删除所有的本地lib二进制文件,并让它使用安装在手机上的Android Opencv manager,但我不完全清楚它是如何工作的。@medloh:你找到了使用split来减小APK大小的解决方案了吗?是的,我现在正在使用Opencv manager。它大大减少了我的APK的大小,因为我的APK中不再包含本机代码。唯一的缺点是用户必须先安装opencv manager,但如果在您运行应用程序时尚未安装,系统会提示用户自动安装opencv manager。您只需调用OpenCVLoader.initAsync(),它就会神奇地