Android中对'cv::initModule_nonfree()'的未定义引用 [英] Undefined Reference To 'cv::initModule_nonfree()' In Android
问题描述
我想创建一个在本机(使用 C++)中使用 BOW + SVM 进行预测的 Android 应用.不幸的是,我在构建本机部分时遇到了问题.由于 OpenCV SDK for Android 中不包含 non-free 模块,所以我需要自己构建模块,使用 this tutorial.看来我成功构建了 .so 文件.这是输出:
[armeabi-v7a] 预编译:libopencv_java.so <=/home/crash-id/Development/SDK/OpenCV-2.4.9-android-sdk/sdk/native/jni/../libs/armeabi-v7a/[armeabi-v7a] 共享库:libnonfree.so[armeabi-v7a] 安装:libnonfree.so =>库/armeabi-v7a/libnonfree.so[armeabi-v7a] 安装:libopencv_java.so =>库/armeabi-v7a/libopencv_java.so
所以问题来了,当我必须将此 .so 文件添加到我的项目时.我将 libnonfree.so 添加到我的 jni 文件夹中.然后我编辑了 Android.mk.这里我提供了我的 .mk 文件.
Android.mk
LOCAL_PATH := $(call my-dir)包括 $(CLEAR_VARS)LOCAL_MODULE := nonfree_prebuiltLOCAL_SRC_FILES := libnonfree.so包括 $(PREBUILT_SHARED_LIBRARY)包括 $(CLEAR_VARS)OPENCV_CAMERA_MODULES := 开启OPENCV_INSTALL_MODULES := 开启包括/home/crash-id/Development/SDK/OpenCV-2.4.9-android-sdk/sdk/native/jni/OpenCV.mk#LOCAL_SHARED_LIBRARIES := nonfree_prebuilt #如果我添加这个,它表示 cv 命名空间中所有内容的未定义引用.LOCAL_SRC_FILES := SVMDetector.cppLOCAL_MODULE := svm_detectorLOCAL_C_INCLUDES +=/home/crash-id/Development/SDK/OpenCV-2.4.9-android-sdk/sdk/native/jni/includeLOCAL_CFLAGS := -Werror -O3 -ffast-mathLOCAL_LDLIBS += -llog -ldl包括 $(BUILD_SHARED_LIBRARY)
Application.mk
APP_STL := gnustl_staticAPP_CPPFLAGS := -frtti -fexceptionsAPP_ABI := armeabi-v7aAPP_PLATFORM := android-15
但这不起作用.当我尝试构建应用程序时,我收到以下错误:
./obj/local/armeabi-v7a/objs/svm_detector/SVMDetector.o:在函数 Java_org_elsys_thesisdiploma_cammect_FrameProcess_SVMDetect:jni/SVMDetector.cpp:23 中:错误:未定义对cv::initModule_nonfree()"的引用
当我在 initModule_nonfree();
上单击右键时,Eclipse 会打开 nonfree.hpp 文件,其内容如下:
#ifndef __OPENCV_NONFREE_HPP__#define __OPENCV_NONFREE_HPP__#include "opencv2/nonfree/features2d.hpp"命名空间简历{CV_EXPORTS_W bool initModule_nonfree();}#万一
但我不确定链接器是否知道该方法的实现在哪里.因为它给出了一个错误,所以它没有.
编辑
如果我添加 LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
,项目编译成功但会导致运行时错误:
02-17 00:15:58.197: E/AndroidRuntime(8793): 致命异常: main02-17 00:15:58.197: E/AndroidRuntime(8793): 进程: com.example.cammect, PID: 879302-17 00:15:58.197:E/AndroidRuntime(8793):java.lang.UnsatisfiedLinkError:dlopen 失败:找不到libsvm_detector.so"引用的符号_ZN2cv18initModule_nonfreeEv"...
你知道我做错了什么吗?提前致谢!
我的开发环境设置如下:
- android-ndk-r10d(安装路径:
D:adt-bundle-windows-x86_64-20140702android-ndk-r10d
) - OpenCV-2.4.10-android-sdk(安装路径:
D:CODEOpenCV-2.4.10-android-sdk
),下载链接 - OpenCV-2.4.10(安装路径:
D:CODEOpenCV-2.4.10
),下载链接
构建非自由模块
我们其实只需要从
OpenCV-2.4.10
源码中拷贝几个文件到OpenCV-2.4.10-android-sdk
,即:
从OpenCV-2.4.10sourcesmodules onfreeinclude 复制 nonfree 文件夹opencv2
到OpenCV-2.4.10-android-sdksdk ativejniincludeopencv2
.为
libnonfree.so
创建一个文件夹来保存我们的新项目.在这里,我称之为libnonfree
.在libnonfree
下创建一个jni
文件夹.将以下文件从OpenCV-2.4.10sourcesmodules onfreesrc
复制到libnonfreejni
文件夹:- nonfree_init.cpp
- precomp.hpp
- sift.cpp(使用原文件em>)
- surf.cpp(使用原文件em>)
构建
libnonfree.so
:
创建Android.mk
和Application.mk
脚本.这个Android.mk
用于构建libnonfree.so
.- Application.mk
- Android.mk(你应该修改
OPENCV_PATH代码> 您的
OpenCV-2.4.10-android-sdk
所在的位置)
cd
进入项目文件夹libnonfree
并键入ndk-build
以构建libnonfree.so
.
到目前为止,您已经在 libnonfreelibs 中获得了
文件夹.libnonfree.so
以及 libopencv_java.so
和 libgnustl_shared.so
armeabi-v7a
您可以使用这些库轻松构建任何 SIFT 或 SURF 应用程序.如果你想在你的Android应用程序的JAVA代码中使用SIFT和SURF,你只需要为你想要使用的功能编写JNI接口.
构建示例应用程序
创建一个名为
libnonfree_demo
的项目文件夹.在项目文件夹中创建一个jni
文件夹.然后将libnonfree.so
连同libopencv_java.so
和libgnustl_shared.so
复制到jni
中.在
jni 中创建一个 nonfree_jni.cpp代码>.这是一个简单的 SIFT 测试程序.它基本上是读取图像并检测关键点,然后提取特征描述符,最后将关键点绘制到输出图像.
在
jni
中创建Android.mk
和Application.mk
:- Application.mk
- Android.mk(你应该修改
OPENCV_PATH代码> 您的
OpenCV-2.4.10-android-sdk
所在的位置)
cd
进入项目文件夹libnonfree_demo
并输入ndk-build
以构建libnonfree_demo.so
.
此时,您可以使用 SVMDetector
轻松扩展示例应用程序.只需将源文件和包含文件 int 复制到文件夹 libnonfree_demojni
并将 cpp 文件添加到 Android.mk
中的 LOCAL_SRC_FILES
.
整个源代码可以从以下网址下载:https://github.com/bkornel/opencv_android_nonfree.
原文来自:http://web.guohuiwang.com/technical-notes/sift_surf_opencv_androidp>
I want to create an Android app which uses BOW + SVM in native (using C++) for predicting. Unfortunately I have problem with building the native part. Since the non-free module is not included in the OpenCV SDK for Android, I need to build the module myself, using this tutorial. It seems I built the .so file successfully. Here is the output:
[armeabi-v7a] Prebuilt : libopencv_java.so <= /home/crash-id/Development/SDK/OpenCV-2.4.9-android-sdk/sdk/native/jni/../libs/armeabi-v7a/
[armeabi-v7a] SharedLibrary : libnonfree.so
[armeabi-v7a] Install : libnonfree.so => libs/armeabi-v7a/libnonfree.so
[armeabi-v7a] Install : libopencv_java.so => libs/armeabi-v7a/libopencv_java.so
So the problem comes here, when I have to add this .so file to my project. I added libnonfree.so to my jni folder. Then I edited the Android.mk. Here I provide my .mk files.
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := nonfree_prebuilt
LOCAL_SRC_FILES := libnonfree.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
OPENCV_CAMERA_MODULES := on
OPENCV_INSTALL_MODULES := on
include /home/crash-id/Development/SDK/OpenCV-2.4.9-android-sdk/sdk/native/jni/OpenCV.mk
#LOCAL_SHARED_LIBRARIES := nonfree_prebuilt #if I add this, it says undefined reference for everything in the cv namespace.
LOCAL_SRC_FILES := SVMDetector.cpp
LOCAL_MODULE := svm_detector
LOCAL_C_INCLUDES += /home/crash-id/Development/SDK/OpenCV-2.4.9-android-sdk/sdk/native/jni/include
LOCAL_CFLAGS := -Werror -O3 -ffast-math
LOCAL_LDLIBS += -llog -ldl
include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi-v7a
APP_PLATFORM := android-15
But this doesn't work. When I try to build the app, I get the following error:
./obj/local/armeabi-v7a/objs/svm_detector/SVMDetector.o: in function Java_org_elsys_thesisdiploma_cammect_FrameProcess_SVMDetect:jni/SVMDetector.cpp:23: error: undefined reference to 'cv::initModule_nonfree()'
When I click right button on initModule_nonfree();
, Eclipse opens the nonfree.hpp file and here are it's contents:
#ifndef __OPENCV_NONFREE_HPP__
#define __OPENCV_NONFREE_HPP__
#include "opencv2/nonfree/features2d.hpp"
namespace cv
{
CV_EXPORTS_W bool initModule_nonfree();
}
#endif
But I'm not sure the linker knows where is the implementation of this method. Since it gives an error, it doesn't.
EDIT
If I add LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
, the project compiles successfully but it causes run time error:
02-17 00:15:58.197: E/AndroidRuntime(8793): FATAL EXCEPTION: main
02-17 00:15:58.197: E/AndroidRuntime(8793): Process: com.example.cammect, PID: 8793
02-17 00:15:58.197: E/AndroidRuntime(8793): java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "_ZN2cv18initModule_nonfreeEv" referenced by "libsvm_detector.so"...
Do you know what am I doing wrong? Thanks in advance!
My development environment is set up as follows:
- android-ndk-r10d (install path:
D:adt-bundle-windows-x86_64-20140702android-ndk-r10d
) - OpenCV-2.4.10-android-sdk (install path:
D:CODEOpenCV-2.4.10-android-sdk
), Download link - OpenCV-2.4.10 (install path:
D:CODEOpenCV-2.4.10
), Download link
Building the nonfree module
We actually only need to copy a few files from
OpenCV-2.4.10
source code toOpenCV-2.4.10-android-sdk
, namely:
Copy the nonfree folder fromOpenCV-2.4.10sourcesmodules onfreeincludeopencv2
toOpenCV-2.4.10-android-sdksdk ativejniincludeopencv2
.Create a folder to hold our new project for
libnonfree.so
. Here, I call itlibnonfree
. Create ajni
folder underlibnonfree
. Copy the following files fromOpenCV-2.4.10sourcesmodules onfreesrc
tolibnonfreejni
folder:- nonfree_init.cpp
- precomp.hpp
- sift.cpp (use the original file)
- surf.cpp (use the original file)
Building
libnonfree.so
:
CreateAndroid.mk
andApplication.mk
scripts. ThisAndroid.mk
is used to buildlibnonfree.so
.- Application.mk
- Android.mk (you should modify
OPENCV_PATH
where yourOpenCV-2.4.10-android-sdk
is)
cd
into the project folderlibnonfree
and typendk-build
to build thelibnonfree.so
.
So far, you have got libnonfree.so
along with libopencv_java.so
and libgnustl_shared.so
in libnonfreelibsarmeabi-v7a
folder.
You can easily build any SIFT or SURF applications using those libraries. If you want to use SIFT and SURF in JAVA code in your Android application, you only need to write JNI interfaces for the functions you want to use.
Building a sample application
Create a project folder call
libnonfree_demo
. Create ajni
folder inside the project folder. Then copylibnonfree.so
along withlibopencv_java.so
andlibgnustl_shared.so
intojni
.Create a nonfree_jni.cpp in
jni
. It is simple SIFT test program. It basically reads an image and detects the keypoints, then extracts feature descriptors, finally draws the keypoints to an output image.Create
Android.mk
andApplication.mk
insidejni
:- Application.mk
- Android.mk (you should modify
OPENCV_PATH
where yourOpenCV-2.4.10-android-sdk
is)
cd
into the project folderlibnonfree_demo
and typendk-build
to build thelibnonfree_demo.so
.
At this point you can easily extend the sample app with your SVMDetector
. Just copy the source and include files int to the folder libnonfree_demojni
and add cpp files to LOCAL_SRC_FILES
in Android.mk
.
The whole source can be downloaded from: https://github.com/bkornel/opencv_android_nonfree.
Original source from: http://web.guohuiwang.com/technical-notes/sift_surf_opencv_android
这篇关于Android中对'cv::initModule_nonfree()'的未定义引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!