未定义对'的引用;cv::initModule_nonfree()';在Android中
我想创建一个Android应用程序,它在本机中使用BOW+SVM(使用C++)进行预测。不幸的是,我在构建本地部分时遇到了问题。由于Android版OpenCV SDK中不包含非免费模块,因此我需要使用自己构建模块。看来我成功地构建了.so文件。以下是输出:未定义对'的引用;cv::initModule_nonfree()';在Android中,android,opencv,android-ndk,linker,opencv4android,Android,Opencv,Android Ndk,Linker,Opencv4android,我想创建一个Android应用程序,它在本机中使用BOW+SVM(使用C++)进行预测。不幸的是,我在构建本地部分时遇到了问题。由于Android版OpenCV SDK中不包含非免费模块,因此我需要使用自己构建模块。看来我成功地构建了.so文件。以下是输出: [armeabi-v7a] Prebuilt : libopencv_java.so <= /home/crash-id/Development/SDK/OpenCV-2.4.9-android-sdk/sdk/nativ
[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
应用程序.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)
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi-v7a
APP_PLATFORM := android-15
但这不起作用。当我尝试构建应用程序时,出现以下错误:
./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()'
当我在initModule_nonfree()上单击右键时代码>,Eclipse打开nonfree.hpp文件,其内容如下:
#ifndef __OPENCV_NONFREE_HPP__
#define __OPENCV_NONFREE_HPP__
#include "opencv2/nonfree/features2d.hpp"
namespace cv
{
CV_EXPORTS_W bool initModule_nonfree();
}
#endif
但我不确定链接器是否知道该方法的实现在哪里。因为它给出了一个错误,所以它没有
编辑
如果我添加LOCAL\u ALLOW\u UNDEFINED\u符号:=true
,项目将成功编译,但会导致运行时错误:
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"...
你知道我做错了什么吗?提前谢谢 我的开发环境设置如下:
- android-ndk-r10d(安装路径:
D:\adt-bundle-windows-x86\u 64-20140702\android-ndk-r10d\
)
- OpenCV-2.4.10-android-sdk(安装路径:
D:\code\OpenCV-2.4.10-android-sdk\
)
- OpenCV-2.4.10(安装路径:
D:\code\OpenCV-2.4.10\
)
构建非自由模块
实际上,我们只需要将一些文件从OpenCV-2.4.10
源代码复制到OpenCV-2.4.10-android-sdk
,即:
将文件夹从OpenCV-2.4.10\sources\modules\nonfree\include\opencv2\
复制到OpenCV-2.4.10-android-sdk\sdk\native\jni\include\opencv2
为libnonfree.so
创建一个文件夹来保存我们的新项目。在这里,我称之为libnonfree
。在libnonfree
下创建jni
文件夹。将以下文件从OpenCV-2.4.10\sources\modules\nonfree\src
复制到libnonfree\jni\
文件夹:
- (使用原始文件)
- (使用原始文件)
建筑libnonfree.so
:
创建Android.mk
和Application.mk
脚本。这个Android.mk
用于构建libnonfree.so
- (您应该修改您的
OPENCV-2.4.10-android-sdk
所在的OPENCV\u路径)
cd
放入项目文件夹libnonfree
并键入ndk build
以构建libnonfree.so
到目前为止,您已经在libnonfree\libs\armeabi-v7a
文件夹中获得了libnonfree.So
以及libopencv\u java.So
和libgnustl\u.So
。
您可以使用这些库轻松构建任何SIFT或SURF应用程序。如果您想在Android应用程序中使用JAVA代码中的SIFT和SURF,您只需要为您想要使用的函数编写JNI接口
构建示例应用程序
创建项目文件夹调用libnonfree\u demo
。在项目文件夹中创建一个jni
文件夹。然后将libnonfree.so
以及libopencv\u java.so
和libgnustl\u shared.so
复制到jni
中
在jni
中创建一个。这是一个简单的筛选测试程序。它基本上读取图像并检测关键点,然后提取特征描述符,最后将关键点绘制到输出图像
在jni
内部创建Android.mk
和Application.mk
:
- (您应该修改您的
OPENCV-2.4.10-android-sdk
所在的OPENCV\u路径)
cd
放入项目文件夹libnonfree\u demo
并键入ndk build
以构建libnonfree\u demo.so
此时,您可以使用SVMDetector
轻松扩展示例应用程序。只需将源代码和include files int复制到文件夹libnonfree\u demo\jni
,并将cpp文件添加到Android.mk
中的LOCAL\u SRC\u文件中
整个源代码可从以下位置下载:
原始来源:我是否可以补充一点,为了在正在运行的应用程序中使用新库,需要执行以下步骤:
1) 在您的文件夹libnonfree/libs/[TARGET PLATFORM]/中,现在有3个文件:
-libgnustl_shared.so
-libnonfree.so
-libopencv_java.so
在您自己的项目(我的IDE是Android Studio)中,您有一个文件夹src/main/,其中包含以下子文件夹:
-爪哇
-res
创建一个新文件夹(如果还没有):“jniLibs”[此文件夹由Gradle自动解析]
将“libnonfree/libs/”下的上述3个文件夹复制到“jniLibs”文件夹中。你最终会得到这样一个结构:
/app/src/main/jniLibs/[armeabi,armeabi-v7a,…]/[libgnustl_shared.so,libopencv_java.so,libnonfree.so]
2) 在代码中的某个地方,有这样一行代码:
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_10, this, mLoaderCallback);
这一行告诉您的应用程序从本地安装的OpenCV管理器动态加载预编译库。为了使用自编非免费版本,我们将上述行替换为以下内容:
if(!OpenCVLoader.initDebug())
{
}
else
{
System.loadLibrary("nonfree");
}
现在,我们确保使用应用程序提供的非自由包含库
3) 那么,运行一个冲浪描述符:
Bitmap mPhotograph = BitmapFactory.decodeFile(_image_path);
Mat real_image = new Mat();
Utils.bitmapToMat(mPhotograph, real_image);
MatOfKeyPoint keypoints_real = new MatOfKeyPoint();
FeatureDetector detector = FeatureDetector.create(FeatureDetector.SURF);
detector.detect(real_image, keypoints_real);
以前,应用程序会返回一个坏信号,这次它完成了它的工作,你可以评估结果的关键点。你能用zip文件中附加的Android.mk
编译演示程序(test\sift.cpp
)吗?我还没有尝试。我会试着再写一次。你认为我的mk脚本一切正常吗?不,我不认为,因为在没有LOCAL\u SHARED\u LIBRARIES
的情况下,链接器将无法解析nonfree的符号。但正如我在问题中所说,如果我添加带有LOCAL\u SHARED\u LIBRARIES的行,“它表示未定义的引用f”