我在上一篇博客中說到了在Android中集成OpenCV,但是那個版本的OpenCV是沒有SIFT和SURF算法的,因為這些算法是受專利保護的,所以並沒有被包含在預編譯庫中,所以如果想要使用SIFT和SURF算法,需要自己來編譯OpenCV Android SDK。在OpenCV 2.4.x版本中,這些算法被包含在nonfree模塊中;從3.0版本開始,用於圖像特征匹配的一些算法(比如SIFT,SURF,BRIEF,FREAK等)被轉移到了opencv_contrib項目的xfeatures2d模塊中。
我們需要從github上down下opencv_contrib部分內容,將其編譯進去,github地址:https://github.com/opencv/opencv_contrib,注意需要與你下載的OpenCV for Android庫相匹配。關於opencv_contrib庫的編譯,我在Windows和Linux(Ubuntu)中編譯成功(這部分我會在后面的博客中提及),但是在Android平台的編譯遇到我了極大的困難。我百度了很久,找到了一篇相對靠譜的博文:http://johnhany.net/2016/07/build-opencv-manager-for-android-on-ubuntu/,我按照作者所說一步步進行編譯,最終都沒有成功。不過萬幸的是,作者在文章的后面給出了它編譯成功的OpenCV Android SDK,是OpenCV3.2版本的,這里我也給出鏈接:https://pan.baidu.com/s/1kVOejLt,再次感謝作者。不過可惜的是,作者當初編譯的時候僅僅解鎖了SIFT、SURF和FREAK,並沒有解鎖BRIEF,可能不能滿足所有人的要求,這里我也希望如果有大神編譯成功了,將成功后的庫發我一份。
到這里,我們已經擁有了編譯有opencv_contrib部分的Android OpenCV SDK,目錄結構如下:
因為我們需要用到cmake,ndk等工具,所以需要預先打開SDK Manager進行管理(建議安裝SDK Manager當中提供的NDK,便於管理),
然后我們在Android Studio中新建一個項目,新建的時候注意勾選Include C++ Support,之后一直下一步即可。
進入項目后,我們發現項目的目錄結構發生了一定變化,main目錄下多出了一個cpp目錄,而且多出了一個CmakeList文件(Android Studio2之后,我們可以通過cmake管理ndk調用C++,而不用在通過Android.mk文件,這無疑是一個福音)。
然后我們參照我上一篇博客的操作,點擊File->New->Import Module添加庫,點擊File->Project Structure添加依賴,將OpenCVLibrary的build.gradle文件中的一下參數修改為與app的build.gradle文件中相同。
我們要將編譯得到的庫中sdk->native->libs中的文件全部拷貝到項目的main目錄下,重命名為:jniLibs
將編譯得到的庫中sources->opencv_contrib->modules->xfeatures2d->src目錄下的freak.cpp,precomp.hpp,sift.cpp,surf.cpp,surf.hpp,xfeatures2d_init.cpp共6個文件拷貝到app->src->main->cpp文件夾中。其中,precomp.hpp文件需要做如下修改:
注釋掉第52-53行:
1 #include "opencv2/core/private.hpp" 2 #include "opencv2/core/private.cuda.hpp"
注釋掉第62行的
#include "opencv2/core/private.hpp"
然后,我們需要修改CmakeList.txt文件為:
1 cmake_minimum_required(VERSION 3.4.1) 2 3 set(CMAKE_VERBOSE_MAKEFILE on) 4 set(ocvlibs "${CMAKE_SOURCE_DIR}/src/main/jniLibs") 5 include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include) 6 7 add_library(libopencv_java3 SHARED IMPORTED ) 8 set_target_properties(libopencv_java3 PROPERTIES 9 IMPORTED_LOCATION "${ocvlibs}/${ANDROID_ABI}/libopencv_java3.so") 10 11 add_library( # Sets the name of the library. 12 xfeatures2d 13 14 # Sets the library as a shared library. 15 SHARED 16 17 # Provides a relative path to your source file(s). 18 src/main/cpp/xfeatures2d_init.cpp 19 src/main/cpp/sift.cpp 20 src/main/cpp/surf.cpp 21 src/main/cpp/freak.cpp) 22 23 find_library( # Sets the name of the path variable. 24 log-lib 25 26 # Specifies the name of the NDK library that 27 # you want CMake to locate. 28 log ) 29 30 target_link_libraries( # Specifies the target library. 31 xfeatures2d android log libopencv_java3 32 33 # Links the target library to the log library 34 # included in the NDK. 35 ${log-lib} )
最后,我們需要修改app/build.gradle文件為:
1 apply plugin: 'com.android.application' 2 3 android { 4 compileSdkVersion 25 5 buildToolsVersion "27.0.1" 6 defaultConfig { 7 applicationId "com.example.demo02" 8 minSdkVersion 15 9 targetSdkVersion 25 10 versionCode 1 11 versionName "1.0" 12 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 externalNativeBuild { 14 cmake { 15 cppFlags "-std=c++11", "-frtti", "-fexceptions" 16 abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'mips', 'mips64' 17 } 18 } 19 } 20 sourceSets { 21 main { 22 jniLibs.srcDirs = ['src/main/jniLibs'] 23 } 24 } 25 buildTypes { 26 release { 27 minifyEnabled false 28 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 29 } 30 } 31 externalNativeBuild { 32 cmake { 33 path "CMakeLists.txt" 34 } 35 } 36 } 37 38 dependencies { 39 compile 'com.android.support:design:25.3.1' 40 compile fileTree(include: ['*.jar'], dir: 'libs') 41 androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 42 exclude group: 'com.android.support', module: 'support-annotations' 43 }) 44 compile 'com.android.support:appcompat-v7:25.3.1' 45 testCompile 'junit:junit:4.12' 46 compile project(':openCVLibrary320') 47 }
至此,我們就可以在Android中使用SIFT和SURF算法啦,代碼的話,轉道www.baidu.com啦~~~