环境搭建
OpenCV Android版本有三种方式:1.通过OpenCVManager的方式,该方法主要的缺点是在安装自身应用的同时,需要下载OpenCVManager,体验不是太好。优点是不需要编写C、C++代码,相对简单;
@Override public void onResume(){ super.onResume(); OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_8, this, mLoaderCallback); }
2.通过OpenCV Library的方式,同样是不需要编写C、C++代码,只需要引入OpenCV 的Library,一般的路径是OpenCV-3.1.0-android-sdk\OpenCV-android-sdk\sdk\java 将该工程导入eclipse或其他IDE中,设置该工程为Library,方法为右键->Properties->Android,下面有个is Library的选项勾选,这是引入Library的方式,同时,需要在自己创建的工程时引入该Library,方法同上最后一步ADD添加即可,同时需要引入libopencv_java3.so,这是Library依赖的库。
工程中通过静态域的方式引入即可。
static {OpenCVLoader.initDebug();}
3.第三种方式是通过JNI的方式直接处理图片,该方法的优点是方便裁剪,缺点是需要较高的C、C++功底,后面会介绍。
本工程采用第二种方式。
代码实现
package com.wang.opencv;import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;import org.opencv.core.Core;import org.opencv.core.Mat;import org.opencv.android.CameraBridgeViewBase;import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;import org.opencv.android.OpenCVLoader;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.view.WindowManager;public class OpenCameraActivity extends Activity implements CvCameraViewListener2 {private static final String TAG = "OpenCameraActivity";static {OpenCVLoader.initDebug();}private Mat mRgba;private Mat mFlipRgba;private CameraBridgeViewBase mOpenCvCameraView;public OpenCameraActivity() {Log.i(TAG, "Instantiated new " + this.getClass());}/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {Log.i(TAG, "called onCreate");super.onCreate(savedInstanceState);getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);setContentView(R.layout.camera_surface_view);mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.fd_activity_surface_view);mOpenCvCameraView.enableView();//mOpenCvCameraView.setCvCameraViewListener(this);mOpenCvCameraView.setCameraIndex(CameraBridgeViewBase.CAMERA_ID_FRONT);//前置摄像头 CameraBridgeViewBase.CAMERA_ID_BACK为后置摄像头}@Overridepublic void onPause() {super.onPause();if (mOpenCvCameraView != null)mOpenCvCameraView.disableView();}@Overridepublic void onResume() {super.onResume();}public void onDestroy() {super.onDestroy();mOpenCvCameraView.disableView();}public void onCameraViewStarted(int width, int height) {mRgba = new Mat();mFlipRgba = new Mat();}public void onCameraViewStopped() {mRgba.release();}public Mat onCameraFrame(CvCameraViewFrame inputFrame) {mRgba = inputFrame.rgba();//注意Core.flip(mRgba, mFlipRgba, 1);return mFlipRgba;}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {return true;}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {return true;}}
xml配置简单:
<LinearLayout xmlns:android="/apk/res/android"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><org.opencv.android.JavaCameraViewandroid:id="@+id/fd_activity_surface_view"android:layout_width="fill_parent"android:layout_height="fill_parent" /></LinearLayout>
AndroidManifest记得添加摄像头权限。
<uses-permission android:name="android.permission.CAMERA"/>
需要注意的是前置摄像头获取的图像是倒置的,需要通过flip方法翻转一次。
Core.flip(mRgba, mFlipRgba, 1);