我正在嘗試將使用OpenCV用C撰寫的現有計算機視覺代碼移植到Android NDK.我按照此處提供的資訊成功地為Java和NDK匯入了OpenCV庫版本3.4.0(使用官方預構建的Android軟體包):Satck Overflow Answer – CMake configuration of OpenCV on Android.
我能夠使用Java和C中的OpenCV功能編譯和運行一些代碼.但是,我遇到了與某些OpenCV函式相關的2個“未定義參考”鏈接錯誤:持久性JSON讀取器和2D描述符匹配器.
以下是我收到的錯誤訊息:
Build command failed.
Error while executing process D:\Librairies\Android_SDK\cmake\3.6.4111459\bin\cmake.exe with arguments {--build D:\Dev\Android\PageDetector\app\.externalNativeBuild\cmake\debug\x86_64 --target page-recognition-lib}
[1/1] Linking CXX shared library ..\..\..\..\build\intermediates\cmake\debug\obj\x86_64\recognition-lib.so
FAILED: cmd.exe /C "cd . && D:\Librairies\Android_SDK\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=x86_64-none-linux-android --gcc-toolchain=D:/Librairies/Android_SDK/ndk-bundle/toolchains/x86_64-4.9/prebuilt/windows-x86_64 --sysroot=D:/Librairies/Android_SDK/ndk-bundle/sysroot -fPIC -isystem D:/Librairies/Android_SDK/ndk-bundle/sysroot/usr/include/x86_64-linux-android -D__ANDROID_API__=21 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -Wa,--noexecstack -Wformat -Werror=format-security -std=c++11 -std=c++11 -frtti -fexceptions -std=gnu++11 -O0 -fno-limit-debug-info -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a -nostdlib++ --sysroot D:/Librairies/Android_SDK/ndk-bundle/platforms/android-21/arch-x86_64 -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -LD:/Librairies/Android_SDK/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/x86_64 -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libpage-recognition-lib.so -o ..\..\..\..\build\intermediates\cmake\debug\obj\x86_64\recognition-lib.so.so [...] -llog -llog ../../../../src/main/jniLibs/x86_64/libopencv_java3.so -latomic -lm "D:/Librairies/Android_SDK/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/x86_64/libc++_static.a" "D:/Librairies/Android_SDK/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/x86_64/libc++abi.a" && cd ."
D:/Librairies/OpenCV-android-sdk_340/sdk/native/jni/include\opencv2/core/persistence.hpp:1264: error: undefined reference to 'cv::read(cv::FileNode const&, std::__ndk1::vector<cv::KeyPoint, std::__ndk1::allocator<cv::KeyPoint> >&)'
D:\Dev\Android\PageDetector\app\src\main\cpp/PageMatcher.cpp:170: error: undefined reference to 'cv::DescriptorMatcher::radiusMatch(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> > > >&, float, cv::_InputArray const&, bool) const'
clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
以下是編譯器無法鏈接的代碼段:
//code that reads data from a JSON file
this->JSONFeatureFilePath = JSONFeatureFilePath;
cv::FileStorage reader(JSONFeatureFilePath, cv::FileStorage::READ);
this->bookTitle = (string) reader["book_title"];
this->pageNumber = (int) reader["page_num"];
string descType = (string)reader["desc_type"];
replace(descType.begin(), descType.end(), '_', '.');
this->descriptorType = descType;
reader["img_size"] >> this->imageSize;
//this instruction causes the linker error
reader["keypoints"] >> this->keyPoints;
reader["descriptors"] >> this->keyPointDescriptors;
reader["fsum2d"] >> this->fsum2DFeatureSummary;
reader.release();
和
//code performing key point descriptors matching
cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create(cv::DescriptorMatcher::BRUTEFORCE_HAMMING);
vector<vector<cv::DMatch>> matchesTmp;
//instruction responsible for the link error
matcher->radiusMatch(this->sortedMatches.at(refSortedIndex).refImage->getDescriptors(),
this->testImage->getDescriptors(), matchesTmp, matchThreshold);
我已經清楚地確定了導致聯結器錯誤的行,如上面的代碼示例中所述.如果我將它們評論出來,編譯就會完成并且程式運行正常(當然沒有我試圖在NDK中實作的功能).
我的猜測是我呼叫的OpenCV函式在預構建的庫中缺失,或者與我用于NDK開發的編譯器不兼容.我已經嘗試更改OpenCV版本(3.3.0和3.4.0).
有誰知道是什么原因造成這種情況以及如何解決這個問題?它是OpenCV中的已知錯誤還是我的配置不受支持或只是錯誤?
我正在使用Windows 10計算機與Android Studio 3.1.2,NDK r17,構建工具27.0.3和OpenCV 3.4.0預構建的android包(我沒有自己從源代碼編譯).以下是CMake和build.gradle檔案:
CMake的:
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
set(opencv_340_dir D:/Librairies/OpenCV-android-sdk_340/sdk/native/jni)
set(app_dir D:/Dev/Android/PageDetector/app)
# native recognition library API
add_library(recognition-lib
SHARED
src/main/cpp/recognition-lib.h
src/main/cpp/recognition-lib.cpp
# + my classes' h and cpp files
)
# OpenCV lib linking and includes
include_directories(${opencv_340_dir}/include)
add_library(opencv-lib SHARED IMPORTED)
set_target_properties(opencv-lib PROPERTIES IMPORTED_LOCATION ${app_dir}/src/main/jniLibs/${ANDROID_ABI}/libopencv_java3.so)
find_library(log-lib log)
target_link_libraries(
recognition-lib
opencv-lib
${log-lib}
)
target_link_libraries(recognition-lib ${log-lib})
gradle這個:
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.companyname.detector"
minSdkVersion 21
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags "-std=c++11 -frtti -fexceptions"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jniLibs/']
}
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation project(':openCVLibrary340')
}
uj5u.com熱心網友回復:
最近,NDK切換到libc作為默認STL,但OpenCV是用gnustl構建的.externalNativeBuild {
cmake {
arguments "-DANDROID_STL=gnustl_shared"
}
}
為您的圖書館將解決這個問題.
或者,你可以rebuild OpenCV with c++_shared.
uj5u.com熱心網友回復:
您好 您這個問題是怎么解決的呢 想向請教一下問題 方便加下您的微信嗎 非常感謝!轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/230434.html
標籤:其他技術討論專區
