天天看點

OpenCV for Android打開相機

一、知識準備:

1.了解Android工程如何運作在裝置上

2.了解C/C++編譯過程,能夠讀懂makefile

二、實作流程:

1.打開Eclipse,建立一個空白的Android工程:

        項目名稱為OpenCV_Test:

2.為建立工程引入OpenCV Library - 3.1.0庫工程:

        選擇工程,右鍵點選Properties(屬性),然後在Android頁簽中,用Add功能添加一個庫工程引用。

3.打開src目錄下面的MainActivity,由于我們的目标是在應用中通過OpenCV的

Java 

API實作打開相機全屏顯示,并擷取預覽框,是以MainActivity需要實作CvCameraViewListener2接口,可以實作三個方法,分别是:onCameraViewStarted、onCameraViewStopped和onCameraFrame,關鍵的圖像處理寫在onCameraFrame函數中:

4.修改AndroidManifest.xml檔案:

        添加相機的相關權限:

[java] 

view

plain

copy print ? https://code.csdn.net/snippets/1655010 https://code.csdn.net/snippets/1655010/fork

  1. <uses-permission android:name="android.permission.CAMERA"/>  
  2. <uses-feature android:name="android.hardware.camera" android:required="false"/>    
  3. <uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>  

        設定應用的界面主題為沒有頂部标題欄且全屏顯示的,在application标簽中添加:

https://code.csdn.net/snippets/1655010 https://code.csdn.net/snippets/1655010/fork
  1. <application  
  2.         android:allowBackup="true"  
  3.         android:icon="@drawable/ic_launcher"  
  4.         android:label="@string/app_name"  
  5.         android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >  

5.為界面布局檔案添加顯示相機内容的元件:

        打開res/layout下面的activity_main.xml布局檔案,往布局中添加一個OpenCV的視覺元件JavaCameraView:

https://code.csdn.net/snippets/1655010 https://code.csdn.net/snippets/1655010/fork
  1. <RelativeLayout   
  2.     xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:tools="http://schemas.android.com/tools"  
  4.     xmlns:opencv="http://schemas.android.com/apk/res-auto"  
  5.     android:layout_width="match_parent"  
  6.     android:layout_height="match_parent">  
  7.     <org.opencv.android.JavaCameraView   
  8.         android:layout_width="fill_parent"  
  9.         android:layout_height="fill_parent"  
  10.         android:id="@+id/camera_view"  
  11.         opencv:show_fps="true"   
  12.         opencv:camera_id="any"/>  
  13. </RelativeLayout>  

6.回到MainActivity中,完成API的調用:

        聲明一個CameraBridgeViewBase對象,用于存放activity_main.xml中的JavaCameraView元件,并在OnCreate中實作綁定和添加事件監聽:

  1. mCVCamera = (CameraBridgeViewBase) findViewById(R.id.camera_view);  
  2. mCVCamera.setCvCameraViewListener(this);  

7.添加C/C++編譯支援,即Add Native Support,這是為了不依賴于OpenCV Manager,直接引入庫檔案進行編譯:

        記住這裡的填寫的名稱就是引入的庫檔案被編譯生成.so檔案的名稱:

        打開生成的jni目錄下的Android.mk檔案,這個是C/C++編譯和連結時使用到的makefile配置檔案,稍微做一點點修改内容,在“include $(CLEAR_VARS)”後面添加以下内容:

https://code.csdn.net/snippets/1655010 https://code.csdn.net/snippets/1655010/fork
  1. OPENCV_CAMERA_MODULES:=on  
  2. OPENCV_INSTALL_MODULES:=on  
  3. OPENCV_LIB_TYPE:=SHARED  
  4. ifdef OPENCV_ANDROID_SDK  
  5.   ifneq ("","$(wildcard $(OPENCV_ANDROID_SDK)/OpenCV.mk)")  
  6.     include ${OPENCV_ANDROID_SDK}/OpenCV.mk  
  7.   else  
  8.     include ${OPENCV_ANDROID_SDK}/sdk/native/jni/OpenCV.mk  
  9.   endif  
  10. else  
  11.   include ../../sdk/native/jni/OpenCV.mk  
  12. endif  

        如此,我們就完成了庫檔案的引入操作,那麼接下來就是讓相機的輸入幀展示在預覽元件JavaCameraView上。

8.修改public Mat onCameraFrame(CvCameraViewFrame inputFrame)回調函數的内容了,這個函數在相機重新整理每一幀都會調用一次,而且每次的輸入參數就是目前相機視圖資訊,我們直接擷取其中的RGBA資訊作為Mat資料傳回給顯示元件即可:

  1. /** 
  2.      * 圖像處理都寫在此處 
  3.      */  
  4.     @Override  
  5.     public Mat onCameraFrame(CvCameraViewFrame inputFrame) {  
  6.         //直接傳回輸入視訊預覽圖的RGBA資料并存在Mat資料中  
  7.         return inputFrame.rgba();  
  8.     }  

9.以上操作中,我們在OnCreate函數中已經擷取到mCVCamera對象,隻有調用mCVCamera.enableView()之後,預覽元件才會顯示每一幀的Mat圖像,但是在顯示之前我們必須先確定OpenCV的庫檔案已經加載完成,是以調用此方法需要進行異步處理:

  1.      * 通過OpenCV管理Android服務,異步初始化OpenCV 
  2.     BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {  
  3.         @Override  
  4.         public void onManagerConnected(int status){  
  5.             switch (status) {  
  6.             case LoaderCallbackInterface.SUCCESS:  
  7.                 Log.i(TAG,"OpenCV loaded successfully");  
  8.                 mCVCamera.enableView();  
  9.                 break;  
  10.             default:  
  11.             }  
  12.         }  
  13.     };  

            是以隻有當mLoaderCallback收到LoaderCallbackInterface.SUCCESS消息的時候,才會打開預覽顯示,那麼這個消息是從哪裡發出來的呢,這就需要我們重寫Activity的onRusume方法了,因為每次目前Activity激活都會調用此方法,是以可以在此處檢測OpenCV的庫檔案是否加載完畢:

  1. @Override  
  2.     public void onResume() {  
  3.         super.onResume();  
  4.         if (!OpenCVLoader.initDebug()) {  
  5.             Log.d(TAG,"OpenCV library not found!");  
  6.         } else {  
  7.             Log.d(TAG, "OpenCV library found inside package. Using it!");  
  8.             mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);  

三、結果展示:

        至此,我們就完成了裝置相機打開以及輸入預覽資料的擷取,運作在裝置上可以看到: