OpenCV是一個基於BSD許可(開源)發行的跨平臺電腦視覺庫,可以運行在Linux、Windows、Android和Mac OS操作系統上。它輕量級而且高效——由一系列 C 函數和少量 C++ 類構成,同時提供了Python、Ruby、MATLAB等語言的介面,實現了圖像處理和電腦視覺方面的很 ...
OpenCV是一個基於BSD許可(開源)發行的跨平臺電腦視覺庫,可以運行在Linux、Windows、Android和Mac OS操作系統上。它輕量級而且高效——由一系列 C 函數和少量 C++ 類構成,同時提供了Python、Ruby、MATLAB等語言的介面,實現了圖像處理和電腦視覺方面的很多通用演算法。 我們利用它來做一些圖片的處理,能大大的優化記憶體的處理。下麵我來說說接下OpenCV 的三種方式: 一、接入OpenCV 的Java SDK 包,這樣你可以直接在Java調用OpenCV 的大部分方法。第一種方式適用於對Opencv c++ 不熟悉的童鞋,不需要直接調用C++方案, 因為SDK 已經用JNI 全部封裝好了。假設你已經安裝好JDK、AndroidStudio與NDK環境。 先到官網http://opencv.org/releases.html ,下載Android 包,如:opencv-3.2.0-android-sdk.zip。 sdk 目錄提供了Android的API與Java 庫 sdk/java 目錄包含了一個 Eclipse 項目,該項目提供 OpenCV 的Java API,且可以導入到開發環境里。 sdk/native 目錄包含了OpenCV C++ 頭文件(用於JNI),與Android的 .so動態庫 .a靜態庫。 sdk/etc 目錄包含了Haar 與 LBP cascades 級聯。 apk 目錄包含了用戶安裝在指定的Android設備的安裝文件,該文件使opencv 庫可以管理opencv API 首先: File > New > New Module 然後:選擇Import Eclipse ADT Project 把sdk/java 下的項目導入到項目里,然後把這個modules 添加到 app modules里, 直接在 app 目錄下build.gradle 文件里dependencies 大括弧下添加: compile project(':openCVLibrary') 接著在 app/src/main 目錄下 創建一個jniLibs 目錄,然後把sdk/native/libs 下所有文件 拷貝到jniLibs下,編譯,運行。 如果導入後,出現一些android 自帶的類識別不了,那就是因為編譯的SDK版本出錯了。 打開 剛導入 的模塊下 build.gradle 文件,把 compileSdkVersion 與 targetSdkVersion修改成你最新的SDK版本,如:
apply plugin: 'com.android.library' android { compileSdkVersion 25 buildToolsVersion "25.0.0" defaultConfig { minSdkVersion 15 targetSdkVersion 25 } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' } } }運行,則成功了,我發現似乎不需要再安裝額外的 opencv 的apk 了。 下麵鏈接是我添加成功的例子: https://github.com/xiaoxiaoqingyi/NDKDemos OpenCV_java 項目 二、使用opencv sdk 提供的 C++ 頭文件與 .so動態庫 與 .a靜態庫,自己封裝jni,這樣使用的效率會比第一種方法高一些, 且可以100%使用opencv 的介面。下麵看一下安裝的方式: 用AndroidStudio 創建一個項目,然後在 Java 類里創建一個native 方法, 再在app/src/main 下創建 jni,然後創建 cpp 文件對於 native 方法。 以上是一個簡單的jni 方法,你可以查看我以前的 文章: http://www.cnblogs.com/xiaoxiaoqingyi/p/6524165.html 在基本的jni 跑通下,我們把 opencv 庫加入項目里,首先: 1、把 sdk/native 目錄 拷貝到 項目的 jni 目錄下, 然後就是配置 Android.mk文件:
LOCAL_PATH:=$(call my-dir) include $(CLEAR_VARS) OpenCV_INSTALL_MODULES := on OpenCV_CAMERA_MODULES := off OPENCV_LIB_TYPE :=STATIC ifeq ("$(wildcard $(OPENCV_MK_PATH))","") include $(LOCAL_PATH)/native/jni/OpenCV.mk else include $(OPENCV_MK_PATH) endif LOCAL_MODULE := OpenCV LOCAL_SRC_FILES := com_magicing_eigenndk_NDKUtils.cpp LOCAL_LDLIBS += -lm -llog include $(BUILD_SHARED_LIBRARY)
接著配置 Application.mk 文件:
APP_STL := gnustl_static APP_CPPFLAGS := -frtti -fexceptions APP_PLATFORM := android-9最後在 cpp 文件調用 opencv 的方法, 首先導入 #include <opencv2/opencv.hpp> 如:
#include <jni.h> #include <string> #include <iostream> #include <stdio.h> #include <stdlib.h> #include <opencv2/opencv.hpp> using namespace cv; extern "C" JNIEXPORT jintArray JNICALL Java_com_magicing_eigenndk_NDKUtils_gray( JNIEnv *env, jclass obj, jintArray buf, int w, int h) { jint *cbuf; cbuf = env->GetIntArrayElements(buf, JNI_FALSE ); if (cbuf == NULL) { return 0; } Mat imgData(h, w, CV_8UC4, (unsigned char *) cbuf); uchar* ptr = imgData.ptr(0); for(int i = 0; i < w*h; i ++){ //計算公式:Y(亮度) = 0.299*R + 0.587*G + 0.114*B //對於一個int四位元組,其彩色值存儲方式為:BGRA int grayScale = (int)(ptr[4*i+2]*0.299 + ptr[4*i+1]*0.587 + ptr[4*i+0]*0.114); ptr[4*i+1] = grayScale; ptr[4*i+2] = grayScale; ptr[4*i+0] = grayScale; } int size = w * h; jintArray result = env->NewIntArray(size); env->SetIntArrayRegion(result, 0, size, cbuf); env->ReleaseIntArrayElements(buf, cbuf, 0); return result; }然後在 activity 頁面里顯示處理過的圖片,如下:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); NDKUtils ndk = new NDKUtils(); Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable( R.mipmap.pic_test)).getBitmap(); int w = bitmap.getWidth(), h = bitmap.getHeight(); int[] pix = new int[w * h]; bitmap.getPixels(pix, 0, w, 0, 0, w, h); int [] resultPixes=ndk.gray(pix,w,h); Bitmap result = Bitmap.createBitmap(w,h, Bitmap.Config.RGB_565); result.setPixels(resultPixes, 0, w, 0, 0,w, h); ImageView img = (ImageView)findViewById(R.id.img2); img.setImageBitmap(result); } }
運行成功後:
我編譯成功的項目鏈接: https://github.com/xiaoxiaoqingyi/NDKDemos (OpenCV_native項目) 官網參考資料: http://docs.opencv.org/2.4/doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.html#native-c 三、通過opencv 的源碼,重新編譯成 Android sdk 庫,這樣的好處是能獲取到最新的功能,缺點是編譯有點困難(對於不懂C++/C 的童鞋),且新的代碼或許會存在不相容與錯誤。 http://code.opencv.org/projects/opencv/wiki/Building_OpenCV4Android_from_trunk 以上的鏈接是官網推薦的編譯過程,我也嘗試過編譯成功,如果在windows 下安裝Cygwin,然後來編譯是通過不了的,需要重新安裝cmake、shell 以及其它的軟體,編譯的過程確實複雜很多。 我是在MAC下編譯的,只需安裝 cmake軟體,當然也要有NDK的環境。大概的步驟: https://github.com/opencv/opencv 下載opencv 源碼包 1、在mac 下安裝好 cmake 軟體, 2、配置NDK環境變數, 參考百度:http://jingyan.baidu.com/article/d2b1d1029c1ea65c7e37d4c9.html 3、build_android_arm/install 目錄下 得到編譯好的jni 目錄。 如果你想編譯 opencv_contrib 也就是 opencv extra庫的話,你需要把https://github.com/Itseez/opencv_contrib 額外庫包也下載下來。我曾經把opencv_contrib包的tracking模塊 加入到opencv 核心庫,編譯到PC的CodeBlocks開發環境就成功了,但是編譯成Android的環境就出錯了,這個問題我一直沒有解決,最後我換用了其它的方法,我把相應的一些資料提供給大家: https://github.com/alexkarargyris/Caffe_OpenCV_Android_App https://zami0xzami.wordpress.com/2016/03/17/building-opencv-for-android-from-source/ 我參考了上述的資料,在載入opencv 額外庫的時候,編譯了幾次也沒能成功,會報cmake 編譯出錯。我也讓C++ 的同事嘗試用cmake 幫我編譯,也沒能成功,也許我們對cmake 瞭解不夠深,據說opencv extra 庫是需要收費的,所以Android端不能直接編譯進來,但是PC端是成功編譯了的。如有編譯成功的大神,請多多指教!