小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

OpenCV for Android入門

 昵稱14479769 2013-11-03

        在上一篇轉(zhuǎn)載的文章(http://blog.csdn.net/liudekuan/article/details/8569687)中,已經(jīng)對(duì)OpenCV在android環(huán)境的搭建進(jìn)行了比較詳細(xì)的說(shuō)明,但文中所用版本為OpenCV2.3.1,與目前最新版OpenCV-2.4.3.2-android-sdk稍有差異。本文將在新版基礎(chǔ)上進(jìn)行OpenCV4android入門級(jí)說(shuō)明。

 

1.環(huán)境搭建

        進(jìn)行android開(kāi)發(fā)所需要的環(huán)境一般為:eclipse + android sdk + ADT,而OpenCV的開(kāi)發(fā)由于需要編寫(xiě)本地代碼(C/C++),因此還需要安裝以下工具:NDK,Cygwin,CDT。網(wǎng)上都有大量詳細(xì)的安裝講解,本文只描述下其中關(guān)鍵步驟。

1.1 NDK的安裝

        (1) NDK下載后解壓到固定目錄即可,無(wú)需安裝。本文解壓到D盤根目錄下,其路徑為:D:\android-ndk-r8d;

        (2) 添加環(huán)境變量,將其安裝路徑添加到系統(tǒng)path變量中,并添加系統(tǒng)變量NDKROOT:D:\android-ndk-r8d。

1.2 Cygwin的安裝

        (1) 安裝包當(dāng)然可以選擇全部,只是如此以來(lái)則比較耗時(shí)。你也可以只安裝開(kāi)發(fā)NDK用得著的包:autoconf2.1、automake1.10、binutils、gcc-core、gcc-g++、gcc4-core、gcc4-g++、gdb、pcre、pcre-devel、gawk、make;

        (2) 將安裝路徑添加系統(tǒng)變量path中;

        (3) 為了方便的在命令行下調(diào)用Android NDK,找到"C:\cygwin\home\(你的用戶名)"這個(gè)目錄,打開(kāi)文件".bash_profile",在文件的最下面加上下面兩行內(nèi)容:

                NDK=/cygdrive/f/android-ndk-r6b-windows/android-ndk-r6b

                export NDK

1.3 CDT的安裝

        打開(kāi)http://www./cdt/downloads.php,找到對(duì)應(yīng)的repository地址,注意這個(gè)地址對(duì)應(yīng)的Eclipse版本要與第二步中你下載的版本一致。接著,打開(kāi)Eclipse軟件Help->Install New Software菜單安裝即可。

 

2.OpenCV4Android

2.1 下載       

        進(jìn)入官網(wǎng)(http:///)下載OpenCV4Android并解壓,其目錄結(jié)構(gòu)如下:

圖1 OpenCV-2.4.3.2-android-sdk目錄結(jié)構(gòu)

        其中,sdk目錄即是我們開(kāi)發(fā)opencv所需要的類庫(kù);samples目錄中存放著若干opencv應(yīng)用示例(包括人臉檢測(cè)等),可為我們進(jìn)行android下的opencv開(kāi)發(fā)提供參考;doc目錄為opencv類庫(kù)的使用說(shuō)明及api文檔等;而apk目錄則存放著對(duì)應(yīng)于各內(nèi)核版本的OpenCV_2.4.3.2_Manager_2.4應(yīng)用安裝包。此應(yīng)用用來(lái)管理手機(jī)設(shè)備中的opencv類庫(kù),在運(yùn)行opencv應(yīng)用之前,必須確保手機(jī)中已經(jīng)安裝了OpenCV_2.4.3.2_Manager_2.4_*.apk,否則opencv應(yīng)用將會(huì)因?yàn)闊o(wú)法加載opencv類庫(kù)而無(wú)法運(yùn)行。

2.2 將SDK引入工作空間

        (1) 選擇一個(gè)路徑,新建文件夾做為工作空間(我在E盤根目錄下新建workspace目錄來(lái)做為工作空間);

        (2) 將OpenCV-2.4.3.2-android-sdk中的sdk目錄copy至工作空間,并將其更名為OpenCV-SDK(是否更改名稱無(wú)所謂,這是我個(gè)人習(xí)慣而已);

        (3) 以新建的目錄為工作空間,打開(kāi)eclipse;

        (4) 將OpenCV-SDK引入到工作空間中,如下圖所示:

圖2

圖 3

圖4

 

圖5

 

3 開(kāi)發(fā)實(shí)例

        在經(jīng)過(guò)上述的環(huán)境配置之后,就可以進(jìn)行opencv開(kāi)發(fā)了。如http://blog.csdn.net/liudekuan/article/details/8569687所述,android中opencv的開(kāi)發(fā)有兩種方式:直接調(diào)用opencv中的java api;利用JNI編寫(xiě)C++ OpenCV代碼,通過(guò)Android NDK創(chuàng)建動(dòng)態(tài)庫(kù)。本文分別利用這兩種方式實(shí)現(xiàn)圖像的灰度處理操作。

3.1 工程一:通過(guò)調(diào)用OpenCV提供的java api實(shí)現(xiàn)灰度處理

3.1.1 創(chuàng)建工程

        (1) 打開(kāi)eclipse,創(chuàng)建android應(yīng)用工程GrayProcess;

        (2) 將測(cè)試圖像lena.jpg添加到資源目錄res/drawable-hdpi中;

        (3) 在Package Explorer中選擇項(xiàng)目GrayProcess,單擊右鍵在彈出菜單中選擇Properties,然后在彈出的Properties窗口中左側(cè)選擇Android,然后點(diǎn)擊右下方的Add按鈕,選擇OpenCV Library 2.4.3并點(diǎn)擊OK,操作完成后,會(huì)將OpenCV類庫(kù)添加到GrayProcess的Android Dependencies中,如下圖所示:

圖 6

圖7

圖8

3.1.2 工程代碼

        (1) 字符串資源文件:strings.xml

  1. <resources>  
  2.   
  3.     <string name="app_name">GrayProcess</string>  
  4.     <string name="hello_world">Hello world!</string>  
  5.     <string name="menu_settings">Settings</string>  
  6.     <string name="title_activity_main">MainActivity</string>  
  7.     <string name="str_proc">gray process</string>  
  8.     <string name="str_desc">image description</string>  
  9.   
  10. </resources>  


        (2) 布局文件:main.xml

  1. <LinearLayout xmlns:android="http://schemas./apk/res/android"  
  2.     xmlns:tools="http://schemas./tools"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent" >  
  6.       
  7.     <Button   
  8.         android:id="@+id/btn_gray_process"  
  9.         android:layout_width="fill_parent"  
  10.         android:layout_height="wrap_content"  
  11.         android:text="@string/str_proc"/>  
  12.       
  13.     <ImageView  
  14.         android:id="@+id/image_view"  
  15.         android:layout_width="wrap_content"  
  16.         android:layout_height="wrap_content"  
  17.         android:contentDescription="@string/str_proc"/>  
  18.   
  19. </LinearLayout>  


        (3) MainActivity.java

  1. package com.iron.grayprocess;  
  2.   
  3. import org.opencv.android.BaseLoaderCallback;  
  4. import org.opencv.android.LoaderCallbackInterface;  
  5. import org.opencv.android.OpenCVLoader;  
  6. import org.opencv.android.Utils;  
  7. import org.opencv.core.Mat;  
  8. import org.opencv.imgproc.Imgproc;  
  9.   
  10. import android.os.Bundle;  
  11. import android.app.Activity;  
  12. import android.graphics.Bitmap;  
  13. import android.graphics.BitmapFactory;  
  14. import android.graphics.Bitmap.Config;  
  15. import android.view.View;  
  16. import android.view.View.OnClickListener;  
  17. import android.widget.Button;  
  18. import android.widget.ImageView;  
  19.   
  20. public class MainActivity extends Activity implements OnClickListener{  
  21.   
  22.     private Button btnProc;  
  23.     private ImageView imageView;  
  24.     private Bitmap bmp;  
  25.       
  26.     //OpenCV類庫(kù)加載并初始化成功后的回調(diào)函數(shù),在此我們不進(jìn)行任何操作  
  27.     private BaseLoaderCallback  mLoaderCallback = new BaseLoaderCallback(this) {  
  28.         @Override  
  29.         public void onManagerConnected(int status) {  
  30.             switch (status) {  
  31.                 case LoaderCallbackInterface.SUCCESS:{  
  32.                 } break;  
  33.                 default:{  
  34.                     super.onManagerConnected(status);  
  35.                 } break;  
  36.             }  
  37.         }  
  38.     };  
  39.       
  40.     @Override  
  41.     public void onCreate(Bundle savedInstanceState) {  
  42.         super.onCreate(savedInstanceState);  
  43.         setContentView(R.layout.main);  
  44.         btnProc = (Button) findViewById(R.id.btn_gray_process);  
  45.         imageView = (ImageView) findViewById(R.id.image_view);  
  46.         //將lena圖像加載程序中并進(jìn)行顯示  
  47.         bmp = BitmapFactory.decodeResource(getResources(), R.drawable.lena);  
  48.         imageView.setImageBitmap(bmp);  
  49.         btnProc.setOnClickListener(this);  
  50.     }  
  51.   
  52.     @Override  
  53.     public void onClick(View v) {  
  54.         Mat rgbMat = new Mat();  
  55.         Mat grayMat = new Mat();  
  56.         //獲取lena彩色圖像所對(duì)應(yīng)的像素?cái)?shù)據(jù)  
  57.         Utils.bitmapToMat(bmp, rgbMat);  
  58.         //將彩色圖像數(shù)據(jù)轉(zhuǎn)換為灰度圖像數(shù)據(jù)并存儲(chǔ)到grayMat中  
  59.         Imgproc.cvtColor(rgbMat, grayMat, Imgproc.COLOR_RGB2GRAY);  
  60.         //創(chuàng)建一個(gè)灰度圖像  
  61.         Bitmap grayBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), Config.RGB_565);  
  62.         //將矩陣grayMat轉(zhuǎn)換為灰度圖像  
  63.         Utils.matToBitmap(grayMat, grayBmp);  
  64.         imageView.setImageBitmap(grayBmp);  
  65.     }  
  66.       
  67.     @Override  
  68.     public void onResume(){  
  69.         super.onResume();  
  70.         //通過(guò)OpenCV引擎服務(wù)加載并初始化OpenCV類庫(kù),所謂OpenCV引擎服務(wù)即是  
  71.         //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存在于OpenCV安裝包的apk目錄中  
  72.         OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);  
  73.     }  
  74. }  

 

3.1.3 運(yùn)行結(jié)果

       

圖9

 

3.2 工程二:利用JNI編寫(xiě)C++ OpenCV代碼實(shí)現(xiàn)灰度處理

3.2.1 創(chuàng)建工程       

        步驟如工程一,創(chuàng)建新工程GrayProcess2,將lena.jpg添加到資源文件,并按3.1.1所示將opencv類庫(kù)添加到工程中。

3.2.2 編寫(xiě)上層代碼(java)

        (1) res/values/strings.xml

  1. <resources>  
  2.     <string name="app_name">GrayProcess2</string>  
  3.     <string name="hello_world">Hello world!</string>  
  4.     <string name="menu_settings">Settings</string>  
  5.     <string name="title_activity_main">GrayProcess2</string>  
  6.     <string name="str_proc">gray process</string>  
  7.     <string name="str_desc">image description</string>  
  8. </resources>  

       

        (2) res/layout/main.xml

  1. <LinearLayout xmlns:android="http://schemas./apk/res/android"  
  2.     xmlns:tools="http://schemas./tools"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent" >  
  6.       
  7.     <Button   
  8.         android:id="@+id/btn_gray_process"  
  9.         android:layout_width="fill_parent"  
  10.         android:layout_height="wrap_content"  
  11.         android:text="@string/str_proc"/>  
  12.       
  13.     <ImageView  
  14.         android:id="@+id/image_view"  
  15.         android:layout_width="wrap_content"  
  16.         android:layout_height="wrap_content"  
  17.         android:contentDescription="@string/str_proc"/>  
  18.   
  19. </LinearLayout>  

        

        (3)MainActivity.java

  1. package com.iron.grayprocess2;  
  2.   
  3. import org.opencv.android.BaseLoaderCallback;  
  4. import org.opencv.android.LoaderCallbackInterface;  
  5. import org.opencv.android.OpenCVLoader;  
  6. import android.os.Bundle;  
  7. import android.app.Activity;  
  8. import android.graphics.Bitmap;  
  9. import android.graphics.BitmapFactory;  
  10. import android.graphics.Bitmap.Config;  
  11. import android.view.View;  
  12. import android.view.View.OnClickListener;  
  13. import android.widget.Button;  
  14. import android.widget.ImageView;  
  15.   
  16. public class MainActivity extends Activity implements OnClickListener{  
  17.   
  18.     private Button btnProc;  
  19.     private ImageView imageView;  
  20.     private Bitmap bmp;  
  21.       
  22.     //OpenCV類庫(kù)加載并初始化成功后的回調(diào)函數(shù),在此我們不進(jìn)行任何操作  
  23.      private BaseLoaderCallback  mLoaderCallback = new BaseLoaderCallback(this) {  
  24.         @Override  
  25.         public void onManagerConnected(int status) {  
  26.             switch (status) {  
  27.                 case LoaderCallbackInterface.SUCCESS:{  
  28.                     System.loadLibrary("image_proc");  
  29.                 } break;  
  30.                 default:{  
  31.                     super.onManagerConnected(status);  
  32.                 } break;  
  33.             }  
  34.         }  
  35.     };  
  36.       
  37.     @Override  
  38.     public void onCreate(Bundle savedInstanceState) {  
  39.         super.onCreate(savedInstanceState);  
  40.         setContentView(R.layout.main);  
  41.         btnProc = (Button) findViewById(R.id.btn_gray_process);  
  42.         imageView = (ImageView) findViewById(R.id.image_view);  
  43.         //將lena圖像加載程序中并進(jìn)行顯示  
  44.          bmp = BitmapFactory.decodeResource(getResources(), R.drawable.lena);  
  45.         imageView.setImageBitmap(bmp);  
  46.         btnProc.setOnClickListener(this);  
  47.     }  
  48.   
  49.     @Override  
  50.     public void onClick(View v) {  
  51.            
  52.         int w = bmp.getWidth();  
  53.         int h = bmp.getHeight();  
  54.         int[] pixels = new int[w*h];       
  55.         bmp.getPixels(pixels, 0, w, 0, 0, w, h);  
  56.         int[] resultInt = ImageProc.grayProc(pixels, w, h);  
  57.         Bitmap resultImg = Bitmap.createBitmap(w, h, Config.ARGB_8888);  
  58.         resultImg.setPixels(resultInt, 0, w, 0, 0, w, h);  
  59.         imageView.setImageBitmap(resultImg);      
  60.     }  
  61.       
  62.     @Override  
  63.     public void onResume(){  
  64.         super.onResume();  
  65.         //通過(guò)OpenCV引擎服務(wù)加載并初始化OpenCV類庫(kù),所謂OpenCV引擎服務(wù)即是  
  66.         //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存在于OpenCV安裝包的apk目錄中  
  67.         OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);  
  68.     }  
  69. }  

        代碼第28行:System.loadLibrary("image_proc")用來(lái)當(dāng)OpenCV類庫(kù)初始化完成后加載類庫(kù)image_proc。此類庫(kù)由我們來(lái)生成,用于完成圖像灰度處理的操作,此部分將在3.2.3中說(shuō)明。

         (4) ImageProc.java

  1. package com.iron.grayprocess2;  
  2.   
  3. public class ImageProc {  
  4.     public static native int[] grayProc(int[] pixels, int w, int h);  
  5. }  


        ImageProc.java中只定義了方法grayProc,關(guān)鍵字native表明,此方法的實(shí)現(xiàn)由本地代碼(C/C++)來(lái)完成。

3.2.3 編寫(xiě)JNI及C相關(guān)代碼

        在項(xiàng)目中新建目錄jni,在jni目錄中分別添加文件Android.mk,Application.mk,ImageProc.h,ImageProc.cpp,這四個(gè)文件的內(nèi)容分別如下所示。

        (1) Android.mk

  1. LOCAL_PATH := $(call my-dir)  
  2. include $(CLEAR_VARS)  
  3. include ../OpenCV-SDK/native/jni/OpenCV.mk  
  4. LOCAL_SRC_FILES  := ImageProc.cpp  
  5. LOCAL_MODULE     := image_proc  
  6. include $(BUILD_SHARED_LIBRARY)  


代碼說(shuō)明:

第一行:指明當(dāng)前編譯路徑;

第二行:清空變量;

第三行:將OpenCV類庫(kù)中的編譯文件包含進(jìn)來(lái),如此一來(lái)在我們的工程中即可使用OpenCV類庫(kù);

第四行:指定需要編譯的C++源文件;

第五行:指定編譯生成的類庫(kù)名稱;

第六行:調(diào)用命令將源文件編譯為靜態(tài)庫(kù)。

注:第三行指定的路徑很關(guān)鍵,當(dāng)opencv類庫(kù)與工程路徑相關(guān)位置發(fā)生改變時(shí),此路徑也要隨之改變。

        (2) Application.mk(配置文件)

  1. APP_STL := gnustl_static  
  2. APP_CPPFLAGS := -frtti -fexceptions  
  3. APP_ABI := armeabi-v7a  
  4. APP_PLATFORM := android-8  

        (3) ImageProc.h

  1. #include <jni.h>  
  2. extern "C" {  
  3.   
  4. JNIEXPORT jintArray JNICALL Java_com_iron_grayprocess2_ImageProc_grayProc  
  5.   (JNIEnv *, jclass, jintArray, jint, jint);  
  6.   
  7. }  


        (4) ImageProc.cpp

  1. #include <ImageProc.h>  
  2. #include <opencv2/core/core.hpp>  
  3. #include <string>  
  4. #include <vector>  
  5.   
  6. using namespace cv;  
  7. using namespace std;  
  8.   
  9. JNIEXPORT jintArray JNICALL Java_com_iron_grayprocess2_ImageProc_grayProc(JNIEnv* env, jclass obj, jintArray buf, jint w, jint h){  
  10.     jint *cbuf;  
  11.     cbuf = env->GetIntArrayElements(buf, false);  
  12.     if(cbuf == NULL){  
  13.         return 0;  
  14.     }  
  15.   
  16.     Mat imgData(h, w, CV_8UC4, (unsigned char*)cbuf);  
  17.   
  18.     uchar* ptr = imgData.ptr(0);  
  19.     for(int i = 0; i < w*h; i ++){  
  20.         //計(jì)算公式:Y(亮度) = 0.299*R + 0.587*G + 0.114*B  
  21.         //對(duì)于一個(gè)int四字節(jié),其彩色值存儲(chǔ)方式為:BGRA  
  22.         int grayScale = (int)(ptr[4*i+2]*0.299 + ptr[4*i+1]*0.587 + ptr[4*i+0]*0.114);  
  23.         ptr[4*i+1] = grayScale;  
  24.         ptr[4*i+2] = grayScale;  
  25.         ptr[4*i+0] = grayScale;  
  26.     }  
  27.   
  28.     int size=w * h;  
  29.     jintArray result = env->NewIntArray(size);  
  30.     env->SetIntArrayRegion(result, 0, size, cbuf);  
  31.     env->ReleaseIntArrayElements(buf, cbuf, 0);  
  32.     return result;  
  33. }  


說(shuō)明:

  •         ImageProc.h頭文件可以通過(guò)jdk提供的工具javah來(lái)生成,具體使用說(shuō)明請(qǐng)參考相關(guān)文檔,本文為演示自己編寫(xiě)了此文件;
  •         JNI中的定義的函數(shù)遵循一定的命名規(guī)則:Java_包名_類名_方法名,具體參考JNI編程相關(guān)知識(shí);
  •         ImageProc.cpp中利用彩色值轉(zhuǎn)換為灰度值的計(jì)算公式,將lena.jpg圖像的每個(gè)像素轉(zhuǎn)換為灰度值,并返回給應(yīng)用層。需要注意的是對(duì)于ARGB_8888類型的圖像而言,其每一個(gè)像素值在int型數(shù)據(jù)中的存儲(chǔ)序列為BGRA。

3.2.4 運(yùn)行

        由于程序中涉及到了JNI編程,因此需要用cygwin對(duì)其中的C/C++代碼進(jìn)行編譯。打開(kāi)cygwin,進(jìn)入到工程的根目錄中執(zhí)行命令:$NDK/ndk-build完成相關(guān)編譯;之后在eclipse中刷新工程GrayProcess2,運(yùn)行即可。編譯及運(yùn)行結(jié)果分別如下所示。

圖10 使用cygwin對(duì)C代碼進(jìn)行編譯

 

圖11 程序運(yùn)行結(jié)果圖對(duì)比

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多