使用OpenCV 3.2.0和Jni在Android上生成错误

时间:2019-02-13 14:06:18

标签: android opencv image-processing opencv4android orb

我正在尝试使用OpenCV和Jni编写一个Android应用程序以比较图像并找到匹配项。我已经在android中成功使用了OpenCV 3.2.0(使用官方的预建Android包)。 但是当我尝试使用knnMatch函数时,它给了我这个错误消息:

  Build command failed.
  Error while executing process 
  D:\Android\sdk\cmake\3.6.4111459\bin\cmake.exe with arguments {--build 
  C:\Users\Amine\Desktop\testtt\app\.externalNativeBuild\cmake\debug\arm64- 
  v8a --target native-lib}
  [1/2] Building CXX object CMakeFiles/native-lib.dir/src/main/cpp/native- 
  lib.cpp.o
  [2/2] Linking CXX shared library 
   ..\..\..\..\build\intermediates\cmake\debug\obj\arm64-v8a\libnative-lib.so
  FAILED: cmd.exe /C "cd . && D:\Android\sdk\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe  --target=aarch64-none-linux-android21 --gcc-toolchain=D:/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64 -fPIC --sysroot 
  D:/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64/sysroot -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -fno-addrsig -Wa,--noexecstack -Wformat -Werror=format-security -stdlib=libc++ -frtti -fexceptions -std=gnu++11 -O0 -fno-limit-debug-info  -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a -static-libstdc++ -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--no-undefined -Qunused-arguments -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libnative-lib.so -o ..\..\..\..\build\intermediates\cmake\debug\obj\arm64-v8a\libnative-lib.so 
    CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o   ../../../../src/main/jniLibs/arm64-v8a/libopencv_java3.so -latomic -lm && cd ."
     CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o: In function `toGray(cv::Mat&, cv::Mat&)':

  C:\Users\Amine\Desktop\testtt\app\src\main\cpp/native-lib.cpp:216: undefined reference to `cv::DescriptorMatcher::knnMatch(cv::_InputArray const&, cv::_InputArray const&, std::__ndk1::vector<std::__ndk1::vector<cv::DMatch, std::__ndk1::allocator<cv::DMatch> >, std::__ndk1::allocator<std::__ndk1::vector<cv::DMatch, std::__ndk1::allocator<cv::DMatch> > > >&, int, cv::_InputArray const&, bool) const'

  C:\Users\Amine\Desktop\testtt\app\src\main\cpp/native-lib.cpp:220: undefined reference to `cv::DescriptorMatcher::knnMatch(cv::_InputArray const&, cv::_InputArray const&, std::__ndk1::vector<std::__ndk1::vector<cv::DMatch, std::__ndk1::allocator<cv::DMatch> >, std::__ndk1::allocator<std::__ndk1::vector<cv::DMatch, std::__ndk1::allocator<cv::DMatch> > > >&, int, cv::_InputArray const&, bool) const'

clang ++。exe:错误:链接器命令失败,退出代码为1(使用-v查看调用)

这是我的cpp代码:

std::vector<cv::KeyPoint> keypointsCaptured;
std::vector<cv::KeyPoint> keypointsTarget;

cv::Mat descriptorsCaptured;
cv::Mat descriptorsTarget;
//cv::Mat captured;
std::vector<cv::DMatch> matches;
std::vector<cv::DMatch> symMatches;
orb = ORB::create();

//Pre-process
resize(captured, captured, Size(480,360));
medianBlur(captured, captured, 5);

resize(target, target, Size(480,360));
medianBlur(target, target, 5);

orb->detectAndCompute(captured, noArray(), keypointsCaptured, descriptorsCaptured);
orb->detectAndCompute(target, noArray(), keypointsTarget, descriptorsTarget);
//__android_log_print(ANDROID_LOG_INFO, "sometag", "keypoints2 size = %d", keypointsTarget.size());
//__android_log_print(ANDROID_LOG_INFO, "sometag", "keypoints size = %d", keypointsCaptured.size());

//Match images based on k nearest neighbour
std::vector<std::vector<cv::DMatch> > matches1;
matcher.knnMatch(descriptorsCaptured , descriptorsTarget,
                 matches1, 2);
//__android_log_print(ANDROID_LOG_INFO, "sometag", "Matches1 = %d",     matches1.size());
std::vector<std::vector<cv::DMatch> > matches2;
matcher.knnMatch(descriptorsTarget , descriptorsCaptured,
                 matches2, 2);
//Ratio filter
ratioTest(matches1);
ratioTest(matches2);
symmetryTest(matches1,matches2,symMatches);
ransacTest(symMatches,
           keypointsCaptured, keypointsTarget, matches);

1 个答案:

答案 0 :(得分:0)

此修复程序将NDK版本降低到17c,并像这样编辑Gradle文件:

 externalNativeBuild {
        cmake {
            arguments '-DANDROID_TOOLCHAIN=clang', '-DANDROID_ARM_NEON=TRUE', '-DANDROID_STL=gnustl_shared'
            cFlags '-O3', '-fsigned-char'
            cppFlags "-frtti -fexceptions", '-fsigned-char'
        }
    }

如果您使用的Cmake版本大于3.6,请将其添加到cmake标签下的Gradle中:

  version "3.10.2"