Android Studio 2.2 中利用CAMKE進行OpenCV的NDK開發

來源:互聯網
上載者:User

標籤:jni   list   relative   form   apply   core   3.4   exp   opencv2   

  我在http://www.cnblogs.com/fx-blog/p/8206737.html一文中提到了如何在Android Studio中Java層匯入OpenCV(包含opencv_contrib部分),但是這僅僅是Java層的匯入,隨著學習的深入,我們可以漸漸的發現OpenCV庫對Java的支援不是很給力,比如我使用SIFT演算法時,一般提取出來的特徵點有一萬多個,這其中包含了大量的無效特徵點,如果我想指定特徵點的數目,比如說500個(經過測試,Java中利用OpenCV提取特徵點預設為500),但是OpenCV Java庫中並沒有提供這樣的方法(或者是我沒有發現,如果有大神知曉,還望告知)。但是在C++中,是可以給SIFT指定特徵點的,這裡面就需要有一個在Java中調用C++的功能,Java中我們知道可以利用JNI或者JNA解決,那麼在Androd中我們便可以利用NDK做到Java對C++的調用。

  在Android Studio 2.2之前,我們通常是通過Android.mk和Application.mk兩個檔案設定本地開發;但是在Android Studio 2.2之後的版本,加入了利用CMAKE配置編譯NDK項目的方法,這無疑是一個很好的訊息,我們終於可以拋棄之前那種繁瑣的方法啦,本篇文章只要講的就是在Android Studio中利用CMAKE進行OpenCV的NDK開發。

準備工作:

  首先,我們需要在Android Studio中配置CMAKE、NDK工具,開啟Android Studio 2.2,點擊按鈕開啟SDK Manager,在SDK Platforms中選擇你所需要的Android版本,這裡我使用的是Android 7.0。

    

   在SDK Tools中選擇紅框標出的部分(這裡推薦SDK Manager當中提供的NDK,NDK安裝好後路徑為<Android SDK Path>\ndk-bundle):

    

正式開始:

  建立一個新項目,在建立的過程中,我們需要勾選Include C++ Support,之後的步驟預設即可,可以與http://www.cnblogs.com/fx-blog/p/8206737.html相應正,寫的不是很好,大家見諒。

  項目建立成功之後,會自動在app\src\main下建立一個名為cpp的檔案夾,其中包含一個native-lib.cpp檔案。同時,在app目錄下會多出一個CMakeLists.txt檔案,Android Studio調用CMAKE利用該檔案來協調C++代碼的編譯(預設使用Clang編譯),並將產生的.so檔案提供給apk檔案的打包過程。

  然後需要在Java層匯入OpenCV,OpenCV 3.2 Android SDK可以選用之前編譯好的庫,:https://pan.baidu.com/s/1kVOejLt;在Android Studio中點擊File -> New… -> Import Module,然後在Source Directory中選取<OpenCV 3.2 Android SDK>\sdk\java目錄,這時Module Name就會自動變成“openCVLibrary320”,之後的步驟採用預設設定即可。

  剛剛匯入OpenCV包之後,Android Studio會嘗試自動編譯,由於其預設的build.gradle檔案設定並不適合最新版本,所以會報錯。修改openCVLibrary320\build.gradle為如下內容就會糾正這些錯誤(紅框標出的部分需要與app\build.gradle一致)。

    

   點擊File -> Project Structure,在左邊的Modules中點擊“app”,然後點擊右邊的加號,再選擇Module Dependency,然後在彈出框中選擇:openCVLibrary320。這樣,就為我們的項目app在Java層上添加了OpenCV支援(其中library是我使用的另外一個庫,不用理會)。

    

接下來就是配置利用CMAKE配置OpenCV應用了:

  首先,需要將應用OpenCV C++所需要標頭檔和庫檔案全部複製到項目中,將<OpenCV 3.2 Android SDK>\sdk\native\jni\include檔案夾複製到app\src\main\cpp當中,把<OpenCV 3.2 Android SDK>\sdk\native\libs檔案夾複製到app\src\main當中,並將檔案夾重新命名為jniLibs。

    

  然後將 app\build.gradle修改為(各位看官可以對比修改):

apply plugin: ‘com.android.application‘android {    compileSdkVersion 25    buildToolsVersion "27.0.1"    defaultConfig {        applicationId "com.example.demo02"        minSdkVersion 15        targetSdkVersion 25        versionCode 1        versionName "1.0"        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"        externalNativeBuild {            cmake {                cppFlags "-std=c++11", "-frtti", "-fexceptions"                abiFilters ‘x86‘, ‘x86_64‘, ‘armeabi‘, ‘armeabi-v7a‘, ‘arm64-v8a‘, ‘mips‘, ‘mips64‘            }        }    }    sourceSets {        main {            jniLibs.srcDirs = [‘src/main/jniLibs‘]        }    }    buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile(‘proguard-android.txt‘), ‘proguard-rules.pro‘        }    }    externalNativeBuild {        cmake {            path "CMakeLists.txt"        }    }}dependencies {    compile ‘com.android.support:design:25.3.1‘    compile fileTree(include: [‘*.jar‘], dir: ‘libs‘)    androidTestCompile(‘com.android.support.test.espresso:espresso-core:2.2.2‘, {        exclude group: ‘com.android.support‘, module: ‘support-annotations‘    })    compile ‘com.android.support:appcompat-v7:25.3.1‘    testCompile ‘junit:junit:4.12‘    compile project(‘:openCVLibrary320‘)}

  app\CMakeLists.txt修改為:

cmake_minimum_required(VERSION 3.4.1)set(CMAKE_VERBOSE_MAKEFILE on)set(ocvlibs "${CMAKE_SOURCE_DIR}/src/main/jniLibs")include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include)add_library(libopencv_java3 SHARED IMPORTED )set_target_properties(libopencv_java3 PROPERTIES                      IMPORTED_LOCATION "${ocvlibs}/${ANDROID_ABI}/libopencv_java3.so")add_library( # Sets the name of the library.             native-lib             # Sets the library as a shared library.             SHARED             # Provides a relative path to your source file(s).             src/main/cpp/native-lib.cpp )find_library( # Sets the name of the path variable.              log-lib              # Specifies the name of the NDK library that              # you want CMake to locate.              log )target_link_libraries( # Specifies the target library.                       native-lib android log libopencv_java3                       # Links the target library to the log library                       # included in the NDK.                       ${log-lib} )

  配置部分就此完成了,貼一下關鍵區段的代碼吧,NDK協助類OpenCVNDKHelper:

1 package com.example.ndk;2 3 public class OpenCVNDKHelper {4     static {5         System.loadLibrary("native-lib");6     }7     public native static void detectFeatures(long srcMatAddr, long dstMatAddr);8 }

  C++檔案native-lib.cpp:

 1 #include <jni.h> 2 #include <string> 3 #include <opencv2/core/core.hpp> 4 #include <opencv2/features2d/features2d.hpp> 5 #include <opencv2/xfeatures2d/nonfree.hpp> 6  7 using namespace std; 8 using namespace cv; 9 using namespace xfeatures2d;10 11 extern "C"12 {13     JNIEXPORT void JNICALL Java_com_example_ndk_OpenCVNDKHelper_detectFeatures14         (JNIEnv *, jclass, jlong srcMatAddr, jlong dstMatAddr) {15         Mat* srcMat = (Mat*)srcMatAddr;16         Mat* descriptors = (Mat*)dstMatAddr;17         vector<KeyPoint> Keypoints;18         Ptr<SIFT> detector = SIFT::create(1000);19         detector->detect(*srcMat, Keypoints);20         detector->compute(*srcMat, Keypoints, *descriptors);21     }22 }

  這段代碼主要的作用就是提取Sift特徵(這裡我就不介紹產生.h檔案的過程了,只要掌握.cpp檔案中的函數命名的方法,這個過程是可以省略的啦)。

  補充一點:這個代碼其實也解釋了如何在Java中將Mat傳遞到C++中的方法,在java中的調用如下(src和srcMat為Mat對象):

OpenCVNDKHelper.detectFeatures(src.getNativeObjAddr(), srcMat.getNativeObjAddr());

 

  PS:文章中使用的jniLibs是直接拷貝到目錄中的,這個項目的儲存空間就比較大了,大約1G左右,每次建立項目都需要重新拷貝,大家也可以用軟連結或者絕對路徑代替,這裡就不多介紹啦。但是最終產生的APK檔案大小是差不多的。

  over~~~

 

跑下題:

  寫部落格的過程中,老爸忽然找我視訊交談,我們聊了蠻多,主要就是催我找個女朋友,難道95後也要被家長催找女朋友了嗎,感覺從我6月份畢業以來(可能更早),這個話題就沒有停過啊,腦補過年回家的場面。。。

Android Studio 2.2 中利用CAMKE進行OpenCV的NDK開發

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.