在執行完OpenCV4Android的範例程式後,接著來介紹如何自己建立一個使用OpenCV的App。
由於OpenCV是由C/C++編譯出來的函式庫,如果想要在Android上面呼叫OpenCV函式庫的函式,就必須先將對應版本的函式庫檔案放進去專案裡面。
可是,每一次編譯Android App都要將函式庫包進去apk(Android的App安裝檔)裡面,接著再將安裝檔傳到手機中進行重新安裝,這是非常消耗資源的一件事情。
在Android上要使用OpenCV的函式庫, OpenCV的官網上有提供兩個方法[1],第一個是透過使用由OpenCV官方所提供”OpenCV Manager”的App,這套App會先將OpenCV的函式庫檔案下載進去手機,往後的App如果有使用OpenCV函式庫,會在App執行的時候載入當時所下載的函式庫並進行呼叫;另外一個方法是上面一開始所提到的,將OpenCV函式庫包入自行開發的App,這個方法比較推薦往後要將App發行給其他使用者的時候,就不必請其他使用者下載”OpenCV Manager”的App。
在這篇文章是介紹第一個使用”OpenCV Manager”來進行呼叫OpenCV函式庫的函式,開發的時候會比起另一個方法更為方便。
由於OpenCV是由C/C++編譯出來的函式庫,如果想要在Android上面呼叫OpenCV函式庫的函式,就必須先將對應版本的函式庫檔案放進去專案裡面。
可是,每一次編譯Android App都要將函式庫包進去apk(Android的App安裝檔)裡面,接著再將安裝檔傳到手機中進行重新安裝,這是非常消耗資源的一件事情。
在Android上要使用OpenCV的函式庫, OpenCV的官網上有提供兩個方法[1],第一個是透過使用由OpenCV官方所提供”OpenCV Manager”的App,這套App會先將OpenCV的函式庫檔案下載進去手機,往後的App如果有使用OpenCV函式庫,會在App執行的時候載入當時所下載的函式庫並進行呼叫;另外一個方法是上面一開始所提到的,將OpenCV函式庫包入自行開發的App,這個方法比較推薦往後要將App發行給其他使用者的時候,就不必請其他使用者下載”OpenCV Manager”的App。
在這篇文章是介紹第一個使用”OpenCV Manager”來進行呼叫OpenCV函式庫的函式,開發的時候會比起另一個方法更為方便。
(三)建立Android App並使用OpenCV函式庫(將彩色影像轉成灰階並顯示)。
1.在Eclipse上建立一個新的Android
Application專案。
(1)建立Android Application。
Step1:開啟ADT裡面的Eclipse,在這邊的例子是使用”C:\Document and
Setting\Administrator\workspace”來當成專案的根目錄。
Step2:建立專案。
應用程式名稱(Application
Name):HelloOpenCV4Android
專案名稱(Project
Name): HelloOpenCV4Android
Package Name:com.example.helloopencv4android(建議讓Eclipse自動產生)
最小需求的平台(Minimum
Required SDK):API11 Android
3.0
目標平台(Target SDK):API14 Android 4.0
編譯平台(Compile
With):API14 Android 4.0
產生一個空白的頁面(Blank
Activity)
頁面名稱(Activity
Name):MainActivity
(2)新增ImageView控制項作為顯示處理的結果影像。
Step3:滑鼠左鍵雙點擊"HelloOpenCV4Android/res/layout/activity_main.xml"之後,會看到activity_main所儲存的layout以及其圖像預覽結果(Graphical Layout),將Images & Media類別中的ImageVIew以拖曳的方式移到右邊的預覽圖之中。
Step4:將ImageView拖曳至預覽圖之中之後,Eclipse會請使用者選擇預設影像,在這邊的範例是使用預設值(黑色)。
Step5:按下OK之後,在預覽圖之中就會產生一個以黑色為底的ImageView控制項。
Step6:將顯示方式由Graphical Layout變更至其右邊的activity_main.xml之後,可以看到剛剛所新增的ImageView控制項與預設的TextView控制項之屬性資料。
Step7:由於在這個範例不需要使用文字來呈現,所以將TextView的資料砍掉,並且將ImageView的layout_witdh與layout_height屬性變更至”fill_parent”(填滿父控制項)。
Step8:先將lena.jpg複製到專案的res\drawable-dhpi資料夾之中,以這個例子來講,完整路徑: "C:\Document and
Setting\Administrator\workspace\HelloOpenCV4Android\res\drawable-dhpi"。
Step9:在Eclipse上,對專案的res資料夾使用滑鼠右鍵點擊並選擇更新(Refresh),這樣Eclipse就會幫使用者新增專案的變數,讓使用者方便使用那一個變數進行讀取。
(4)設定OpenCV的jar(java的函式庫檔案),並將OpenCV設定成與App一起編入apk之中。
Step10:對專案的資料夾滑鼠右鍵點擊並選擇屬性(Properties)。
Step11:在Java Build Path的類別上,選擇Libraries頁面,並點選Add External JARs…。
Step12:選擇OpenCV4Android的sdk\java\bin\opencv
library – 2.4.9.jar(一定要先完成OpenCV4Android的範例程式才會產生)。
Step13:新增完成後,選擇Order and Export的頁面,將opencv library – 2.4.9.jar的選項打勾,這樣才會將opencv library –
2.4.9包在這個專案。
Step14:由於編譯器的設定已經變更,接下來Eclipse會需要重建整個專案。
(5)新增將圖片轉為灰階的程式碼並連上手機進行測試。
Step15:在MainActivity.java之中新增以下程式碼。
由於OpenCV函式庫是使用C/C++所編譯而成的函式庫,所以在Java端必須先載入OpenCV函式庫到這個App之後方能使用OpenCV的函式,以下是Java載入OpenCV函式庫的程式碼(包含轉灰階並顯示):
//非同步載入OpenCV函式庫 private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) { @Override public void onManagerConnected(int status) { switch (status) { case LoaderCallbackInterface.SUCCESS: { System.out.println("load opencv lib SUCCESS!!"); //從resource讀取影像 InputStream is = getResources().openRawResource(R.drawable.lena); Bitmap img = BitmapFactory.decodeStream(is); if (img != null) { Mat m = new Mat() , grayM = new Mat() ; //將bitmap轉成OpenCV的Mat型態 Utils.bitmapToMat(img, m); //將影像轉換成灰階 Imgproc.cvtColor(m, grayM, Imgproc.COLOR_BGR2GRAY); //因為Android顯示的時候需要使用BGRA的格式 所以必須將灰階(channel = 1)擴展成BGRA(channel = 4) Imgproc.cvtColor(grayM, m, Imgproc.COLOR_GRAY2BGRA); //將OpenCV的Mat型態轉成Bitmap型態 Bitmap bm = Bitmap.createBitmap(m.cols(), m.rows(),Bitmap.Config.ARGB_8888); Utils.matToBitmap(m, bm); //尋找貼圖的ImageView ImageView iView = (ImageView) findViewById(R.id.imageView1) ; //將圖片設定到ImageView iView.setImageBitmap(bm) ; //釋放暫存的影像記憶體空間 m.release(); grayM.release() ; img.recycle() ; } } break; default: { super.onManagerConnected(status); } break; } } };
在MainActivity的onCreate的事件上新增:
//非同步初始化OpenCV OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_9 , this , mLoaderCallback ) ;
完整的程式碼:
package com.example.helloopencv4android; import java.io.InputStream; import org.opencv.android.BaseLoaderCallback; import org.opencv.android.LoaderCallbackInterface; import org.opencv.android.OpenCVLoader; import org.opencv.android.Utils; import org.opencv.core.Mat; import org.opencv.imgproc.Imgproc; import android.support.v7.app.ActionBarActivity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.widget.ImageView; public class MainActivity extends ActionBarActivity { //非同步載入OpenCV函式庫 private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) { @Override public void onManagerConnected(int status) { switch (status) { case LoaderCallbackInterface.SUCCESS: { System.out.println("load opencv lib SUCCESS!!"); //從resource讀取影像 InputStream is = getResources().openRawResource(R.drawable.lena); Bitmap img = BitmapFactory.decodeStream(is); if (img != null) { Mat m = new Mat() , grayM = new Mat() ; //將bitmap轉成OpenCV的Mat型態 Utils.bitmapToMat(img, m); //將影像轉換成灰階 Imgproc.cvtColor(m, grayM, Imgproc.COLOR_BGR2GRAY); //因為Android顯示的時候需要使用BGRA的格式 所以必須將灰階(channel = 1)擴展成BGRA(channel = 4) Imgproc.cvtColor(grayM, m, Imgproc.COLOR_GRAY2BGRA); //將OpenCV的Mat型態轉成Bitmap型態 Bitmap bm = Bitmap.createBitmap(m.cols(), m.rows(),Bitmap.Config.ARGB_8888); Utils.matToBitmap(m, bm); //尋找貼圖的ImageView ImageView iView = (ImageView) findViewById(R.id.imageView1) ; //將圖片設定到ImageView iView.setImageBitmap(bm) ; //釋放暫存的影像記憶體空間 m.release(); grayM.release() ; img.recycle() ; } } break; default: { super.onManagerConnected(status); } break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //非同步初始化OpenCV OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_9 , this , mLoaderCallback ) ; } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }Step16:對專案的資料夾滑鼠右鍵點擊並選擇Run As->Android Application執行這隻程式。
Step17:選擇執行這隻程式的機器。
(6)手機端應用程式執行的流程。
Step18:手機執行這支App之後,發現手機上沒有安裝”OpenCV Manager”,會要求使用者進行安裝。
Step19:進入Google Play商店之後,直接點選安裝,等到下載並安裝結束即可。
Step20:再次進入App,就可以看到lena轉成灰階的影像。
沒有留言:
張貼留言