未定义对 'cv::CascadeClassifier::detectMultiScale' 的引用,但其他库已正确链接
undefined reference to 'cv::CascadeClassifier::detectMultiScale', but other lib linked properly
我正在使用 NDK 执行一些 opencv 函数,看看使用 c++ 是否会加快处理速度(我在另一个项目中使用了 Java Wrappers)。在我的 class 中添加 detectMultiScale 函数之前,所有编译都很好,链接器突然失败并产生了 未定义的引用错误 。如果我注释掉该行,错误就会消失。
我在网上进行了搜索,但除了 之外似乎没有人遇到过相同的问题,其中没有给出任何答案。如果有人能找到另一个相关的 post,请随时指导我:)
平台:Windows10,
Android 工作室 2,
OpenCV 3.1(自己重新编译加入人脸模块)
main.cpp
#include <jni.h>
#include <string>
#include <android/log.h>
#include "com_yk_iskl_jnitest_FaceRecognition.h"
#define LOG_TAG "libnativeface"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
class FaceRecognition{
private:
cv::Ptr<cv::face::LBPHFaceRecognizer> lbph_model;
cv::Ptr<cv::face::FaceRecognizer> fisher_model;
cv::Ptr<cv::face::FaceRecognizer> eigen_model;
cv::CascadeClassifier face_cascade;
cv::CascadeClassifier eye_cascade;
public:
void loadLBPHModel(std::string& filepath)
{
lbph_model=cv::face::createLBPHFaceRecognizer();
try{
lbph_model->load(filepath);
}catch(cv::Exception e){
LOGE("%s",(e.msg).c_str());
}
lbph_model->setThreshold(999);
}
void loadFaceCascade(std::string& filepath)
{
try{
face_cascade.load(filepath);
}catch(cv::Exception e){
LOGE("%s",(e.msg).c_str());
}
}
void loadEyeCascade(std::string& filepath)
{
try{
eye_cascade.load(filepath);
}catch(cv::Exception e){
LOGE("%s",(e.msg).c_str());
}
}
double getThreshold()
{
return lbph_model->getThreshold();
}
std::vector<cv::Rect> detectFace(cv::Mat src)
{
std::vector<cv::Rect> faces;
face_cascade.detectMultiScale(src, faces, 1.1, 2, 0 | cv::CASCADE_SCALE_IMAGE, cv::Size(30, 30)); <--------------------------Heres the problem
return faces;
}
};
//---------------------------
JNIEXPORT jlong JNICALL
Java_com_yk_iskl_jnitest_FaceRecognition_createNativeFaceRecognition(JNIEnv *, jclass)
{
return (jlong)(new FaceRecognition());
}
JNIEXPORT void JNICALL
Java_com_yk_iskl_jnitest_FaceRecognition_loadLBPHModel(JNIEnv * env, jclass, jlong native_addr, jstring filename)
{
std::string fn((const char*)env->GetStringUTFChars(filename,0));
((FaceRecognition*)native_addr)->loadEyeCascade(fn);
}
JNIEXPORT void JNICALL
Java_com_yk_iskl_jnitest_FaceRecognition_loadEyeCascade(JNIEnv * env, jclass, jlong native_addr, jstring filename)
{
std::string fn((const char*)env->GetStringUTFChars(filename,0));
((FaceRecognition*)native_addr)->loadLBPHModel(fn);
}
JNIEXPORT jdouble JNICALL
Java_com_yk_iskl_jnitest_FaceRecognition_getThreshold(JNIEnv *env, jclass, jlong native_addr)
{
return (jdouble)((FaceRecognition*)native_addr)->getThreshold();
}
JNIEXPORT void JNICALL
Java_com_yk_iskl_jnitest_FaceRecognition_process(JNIEnv *env, jclass, jlong native_addr, jlong frame_addr)
{
cv::Mat* pframe_addr = (cv::Mat*)frame_addr;
cv::cvtColor(*pframe_addr,*pframe_addr,cv::COLOR_YUV420sp2GRAY);
std::vector<cv::Rect> faces=((FaceRecognition*)native_addr)->detectFace(*pframe_addr);
}
JNIEXPORT void JNICALL
Java_com_yk_iskl_jnitest_FaceRecognition_testReturns(JNIEnv *env, jclass, jlong native_addr, jobjectArray string, jintArray num)
{
//Get pointer from num
jint* parray=env->GetIntArrayElements(num,0);
parray[0]=888;
//Copy back to num
env->SetIntArrayRegion(num,0,1,parray);
}
//---------------------------
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
#opencv
OPENCVROOT:= C:\Users\<hidden>\Desktop\PROGRAMMING\OPENCV_ANDROID_BUILD\install
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
OPENCV_LIB_TYPE:=SHARED
include ${OPENCVROOT}\sdk\native\jni\OpenCV.mk
#include $(CLEAR_VARS)
LOCAL_SRC_FILES := main.cpp
LOCAL_LDLIBS += -lz -lm -llog -landroid -ldl
LOCAL_MODULE := nativeface
include $(
我在执行 ndk 构建时遇到了以下错误
C:/Users/<hidden>/AndroidStudioProjects/JNITEST/app/src/main/jni/main.cpp:59: error: undefined reference to 'cv::CascadeClassifier::detectMultiScale(cv::_InputArray const&, std::__ndk1::vector<cv::Rect_<int>, std::__ndk1::allocator<cv::Rect_<int> > >&, double, int, int, cv::Size_<int>, cv::Size_<int>)'
collect2.exe: error: ld returned 1 exit status
make: *** [C:\Users\<hidden>\AndroidStudioProjects\JNITEST\app/build/intermediates/ndk/obj/local/armeabi-v7a/libnativeface.so] Error 1
如果大家需要更多信息,尽管提出,我会尽量提供更多信息。
经过长时间的排查和测试,我发现问题出在我的Application.mk。添加以下行可解决问题;
APP_STL:=gnustl_shared
从这个 response 得到的想法让我思考我是否缺少 stl。
我正在使用 NDK 执行一些 opencv 函数,看看使用 c++ 是否会加快处理速度(我在另一个项目中使用了 Java Wrappers)。在我的 class 中添加 detectMultiScale 函数之前,所有编译都很好,链接器突然失败并产生了 未定义的引用错误 。如果我注释掉该行,错误就会消失。
我在网上进行了搜索,但除了 之外似乎没有人遇到过相同的问题,其中没有给出任何答案。如果有人能找到另一个相关的 post,请随时指导我:)
平台:Windows10, Android 工作室 2, OpenCV 3.1(自己重新编译加入人脸模块)
main.cpp
#include <jni.h>
#include <string>
#include <android/log.h>
#include "com_yk_iskl_jnitest_FaceRecognition.h"
#define LOG_TAG "libnativeface"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
class FaceRecognition{
private:
cv::Ptr<cv::face::LBPHFaceRecognizer> lbph_model;
cv::Ptr<cv::face::FaceRecognizer> fisher_model;
cv::Ptr<cv::face::FaceRecognizer> eigen_model;
cv::CascadeClassifier face_cascade;
cv::CascadeClassifier eye_cascade;
public:
void loadLBPHModel(std::string& filepath)
{
lbph_model=cv::face::createLBPHFaceRecognizer();
try{
lbph_model->load(filepath);
}catch(cv::Exception e){
LOGE("%s",(e.msg).c_str());
}
lbph_model->setThreshold(999);
}
void loadFaceCascade(std::string& filepath)
{
try{
face_cascade.load(filepath);
}catch(cv::Exception e){
LOGE("%s",(e.msg).c_str());
}
}
void loadEyeCascade(std::string& filepath)
{
try{
eye_cascade.load(filepath);
}catch(cv::Exception e){
LOGE("%s",(e.msg).c_str());
}
}
double getThreshold()
{
return lbph_model->getThreshold();
}
std::vector<cv::Rect> detectFace(cv::Mat src)
{
std::vector<cv::Rect> faces;
face_cascade.detectMultiScale(src, faces, 1.1, 2, 0 | cv::CASCADE_SCALE_IMAGE, cv::Size(30, 30)); <--------------------------Heres the problem
return faces;
}
};
//---------------------------
JNIEXPORT jlong JNICALL
Java_com_yk_iskl_jnitest_FaceRecognition_createNativeFaceRecognition(JNIEnv *, jclass)
{
return (jlong)(new FaceRecognition());
}
JNIEXPORT void JNICALL
Java_com_yk_iskl_jnitest_FaceRecognition_loadLBPHModel(JNIEnv * env, jclass, jlong native_addr, jstring filename)
{
std::string fn((const char*)env->GetStringUTFChars(filename,0));
((FaceRecognition*)native_addr)->loadEyeCascade(fn);
}
JNIEXPORT void JNICALL
Java_com_yk_iskl_jnitest_FaceRecognition_loadEyeCascade(JNIEnv * env, jclass, jlong native_addr, jstring filename)
{
std::string fn((const char*)env->GetStringUTFChars(filename,0));
((FaceRecognition*)native_addr)->loadLBPHModel(fn);
}
JNIEXPORT jdouble JNICALL
Java_com_yk_iskl_jnitest_FaceRecognition_getThreshold(JNIEnv *env, jclass, jlong native_addr)
{
return (jdouble)((FaceRecognition*)native_addr)->getThreshold();
}
JNIEXPORT void JNICALL
Java_com_yk_iskl_jnitest_FaceRecognition_process(JNIEnv *env, jclass, jlong native_addr, jlong frame_addr)
{
cv::Mat* pframe_addr = (cv::Mat*)frame_addr;
cv::cvtColor(*pframe_addr,*pframe_addr,cv::COLOR_YUV420sp2GRAY);
std::vector<cv::Rect> faces=((FaceRecognition*)native_addr)->detectFace(*pframe_addr);
}
JNIEXPORT void JNICALL
Java_com_yk_iskl_jnitest_FaceRecognition_testReturns(JNIEnv *env, jclass, jlong native_addr, jobjectArray string, jintArray num)
{
//Get pointer from num
jint* parray=env->GetIntArrayElements(num,0);
parray[0]=888;
//Copy back to num
env->SetIntArrayRegion(num,0,1,parray);
}
//---------------------------
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
#opencv
OPENCVROOT:= C:\Users\<hidden>\Desktop\PROGRAMMING\OPENCV_ANDROID_BUILD\install
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
OPENCV_LIB_TYPE:=SHARED
include ${OPENCVROOT}\sdk\native\jni\OpenCV.mk
#include $(CLEAR_VARS)
LOCAL_SRC_FILES := main.cpp
LOCAL_LDLIBS += -lz -lm -llog -landroid -ldl
LOCAL_MODULE := nativeface
include $(
我在执行 ndk 构建时遇到了以下错误
C:/Users/<hidden>/AndroidStudioProjects/JNITEST/app/src/main/jni/main.cpp:59: error: undefined reference to 'cv::CascadeClassifier::detectMultiScale(cv::_InputArray const&, std::__ndk1::vector<cv::Rect_<int>, std::__ndk1::allocator<cv::Rect_<int> > >&, double, int, int, cv::Size_<int>, cv::Size_<int>)'
collect2.exe: error: ld returned 1 exit status
make: *** [C:\Users\<hidden>\AndroidStudioProjects\JNITEST\app/build/intermediates/ndk/obj/local/armeabi-v7a/libnativeface.so] Error 1
如果大家需要更多信息,尽管提出,我会尽量提供更多信息。
经过长时间的排查和测试,我发现问题出在我的Application.mk。添加以下行可解决问题;
APP_STL:=gnustl_shared
从这个 response 得到的想法让我思考我是否缺少 stl。