最近看了一些opencv的相關內容,這裏作一下記錄以及學習中的體會,和你們分享一下,本人在學習的時候也是網上查閱不少人的博客。html
如今都是開源時代,opencv也是一個開源庫,也有官網和社區,因此簡介什麼的你們去官網看看,瞭解什麼是opencv,用來幹什麼的,這裏就不羅嗦了。java
各個版本下載地址,python
能夠根據本身的工做平臺下載對應的資源,本人實在android的領域下使用opencv,因此下載的是3.4.5 Android pack,後面的內容也是針對opencv在android開發中的使用。android
下載解壓後的文件結構以下c++
opencv底層是c/c++寫的,語言門檻高,另外涉及的數學、圖形學等知識也加大了學習難度,因此官方針對不一樣水平和應用方向的人員提供了不一樣的開發方式,以造福廣大的opencv能力須要者。git
一、要不要在項目中配置sdk中native庫?github
在使用opencv能力以前,須要加載opencv提供的native庫,opencv提供了兩種方式:算法
爲何opencv要提供這兩種方式呢?編程
緣由就在於上面說過opencv的native庫文件體積比較大。api
若是是從本地包進行加載,設備上安裝的應用不少都使用opencv的話,每一個應用下都要拷貝一份native庫文件,浪費存儲空間,另外項目中配置native庫也相對繁瑣。
雖然設備上提早安裝 opencv-manager的方式節省了存儲空間,可是一個硬傷就是不能保證用戶設備上實現安裝了opencv-manager,再說了,用戶也不會爲了你的一個app而提早安裝另一個app,用戶纔不會聽你的。
因此,本身學習或者開發demo的時候能夠用提早安裝 opencv-manager的方式,省去了拷貝、配置native庫的操做,也節省了手機空間。可是若是開發正式的app仍是老老實實的從本地包加載爲好。
二、涉不涉及ndk開發?
android開發目前來講java還是主流,kotlin雖然愈來愈流行,可是對java是全兼容的。 opencv底層是c/c++實現的。 因此android中使用opencv能力就須要解決兩種語言通訊的問題,使用的方案固然是jni啦,opencvsdk的java工程對jni調用opencv方法進行了封裝,開發時直接調用封裝好的java方法便可實現opencv能力的調用,很爽吧,不用和c/c++打交道。
可是畢竟opencv底層是c/c++實現的,想要100%使用opencv的能力,或者sdk的java庫中提供的方法不能知足需求,仍是須要本身使用c/c++去實現一部分功能,自行封裝成jni方法使用。再說了如今都是團隊開發,能夠有專門的小夥伴實現底層的工做,對吧,這就須要拷貝、配置相關的native庫,使用ndk進行開發。
固然了,更厲害的大神能夠下載源碼進行修改,自行編譯,不只能夠獲得最新的sdk,並且可以根據須要,自行實現底層相關算法之類的。
這裏對不一樣的開發機制的適用場景進行簡單的總結:
通過上面的討論,對android下opencv的開發機制有了大概瞭解,下面的分別對幾種開發方式進行簡單的實現。
一、java庫+opencv-manager.apk
準備
須要準備的東西是sdk的java庫工程以及設備平臺對應的opencv-manager.apk
配置
File-New-Import module
,定位到java庫工程,導入後庫工程的module name 爲openCVLibrary343implementation project(':openCVLibrary343')
,而後同步代碼便可。開發
在 Activity 的 onResume 方法中初始化opencv
//使用OpenCV Engine service,須要運行設備事先安裝OpenCV Manager
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION, this, new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
if (status == LoaderCallbackInterface.SUCCESS) {
Log.d(TAG, "onManagerConnected: success");
} else {
super.onManagerConnected(status);
}
}
});
複製代碼
對圖片進行均值模糊
//本地加載圖片
Bitmap originImg = BitmapFactory.decodeFile("filePath");
//初始化Mat
Mat src = new Mat(originImg.getHeight(), originImg.getWidth(), CvType.CV_8UC4);
//bitmap轉mat
Utils.bitmapToMat(originImg, src);
//均值模糊
Imgproc.blur(src, src, new Size(3, 3));
//初始化處理後bitmap
Bitmap processedImg = Bitmap.createBitmap(src.cols(), src.rows(), Bitmap.Config.ARGB_8888);
//mat轉bitmap
Utils.matToBitmap(src, processedImg);
複製代碼
二、java庫+native庫
和上種方式的區別在於:
準備
須要準備的東西是sdk的java庫工程、native庫(sdk-native-libs)
配置
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jniLibs/libs']
}
}
複製代碼
開發
和【java庫+opencv-manager.apk】開發方式初始化opencv的時候有區別,其餘都同樣。
在 Activity 的 onResume 方法中初始化opencv
//使用應用本地native庫
OpenCVLoader.initDebug();
複製代碼
三、java庫+native庫+自行封裝實現的jni方法
這種方式是在【java庫+native庫】開發方式的基礎上使用ndk進行jni開發。
準備
須要準備的東西是sdk的java庫工程、native庫(sdk-native-libs)、native庫頭文件(sdk-native-jni-include)
配置
cmake_minimum_required(VERSION 3.4.1)
include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include)
add_library(libopencv_java3 SHARED IMPORTED)
set_target_properties(libopencv_java3 PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jniLibs/libs/${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 libopencv_java3
# Links the target library to the log library
# included in the NDK.
${log-lib} )
複製代碼
開發
看demo吧,就是jni開發那一套。
android中使用opencv進行開發時,針對不一樣的開發和應用場景選擇開發方式,總的來講涉及的東西挺多的,android知識、ndk/jni知識、c/c++知識、opencv知識、數學知識等。
學習的時候以android 開發爲基礎,經過本文搭建起開發框架,在寫demo的過程當中學習opencv api和相關的理論知識,同時也學習了ndk/jni和c/c++。