绪论
对于Android移动端的相机调用及数据读取,OpenCV是把原来C++的部分与本地AndroidSDK进行了整合,通过桥接的方式调用Android手机摄像头,最重要的一个类是JavaCameraView,它是OpenCV中调用Android手机摄像头的接口类,支持以代码和XMLView配置的方式使用,可以在Android设备中使用摄像头完成前置与后置摄像头的预览与拍照功能,下面就对这些内容逐一加以说明,并完成代码演示。
目录
一、显示预览帧
1、修改AndroidManifest.xml文件:
- 添加相机的相关权限:
因为在Android中使用SD卡、相机卡等本地硬件资源的时候会涉及授权问题,而且Android的低版本与高版本的授权方式有点不一样。这里首先需要说明一下Android在不同版本上的相机授权差别,Android在低版本中是通过向AndroidManifests.xml中添加文本的方式来完成授权的,添加内容如下:
<!--Allow to use a camera-->
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<uses-feature android:name="android.hardware.camera.front" android:required="false"/>
<uses-feature android:name="android.hardware.camera.front.autofocus" android:required="false"/>
这种方式在Android 6.0以下的版本上使用没有问题,但是在Android 6.0以上的版本中(包括6.0)就会出现问题,原因是Android系统的授权方式改变升级了,所以需要在onCreat中添加如下的代码进行授权:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions( new String[]{
Manifest.permission.CAMERA}, 203);
}
- 设置应用的界面主题为没有顶部标题栏且全屏显示的,在application标签中添加:
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" <!--显示当前的帧率-->
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"> <!--Full screen mode-->
- 设置横竖屏显示,在application-activity标签中添加:
android:screenOrientation="landscape" //屏幕的控制
2、为界面布局文件添加显示相机内容的组件:
打开res/layout下面的activity_main.xml布局文件,往布局中添加一个OpenCV的视觉组件JavaCameraView:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:opencv="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.opencv.android.JavaCameraView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/camera_view"
opencv:show_fps="true"
opencv:camera_id="any"/>
</RelativeLayout>
3、在MainActivity中调用API
打开src目录下面的MainActivity,由于我们的目标是在应用中通过OpenCV的Java API实现打开相机全屏显示,并获取预览框,所以MainActivity需要实现CvCameraViewListener2接口,可以实现三个方法,分别是:onCameraViewStarted、onCameraViewStopped和onCameraFrame,关键的图像处理写在onCameraFrame函数中:
调用API
声明一个JavaCameraView对象,用于存放activity_main.xml中的JavaCameraView组件,并在OnCreate中实现绑定和添加事件监听:
mCVCamera = (JavaCameraView) findViewById(R.id.camera_view);
mCVCamera.setCvCameraViewListener(this);
修改public Mat onCameraFrame(CvCameraViewFrame inputFrame)回调函数的内容了,这个函数在相机刷新每一帧都会调用一次,而且每次的输入参数就是当前相机视图信息,我们直接获取其中的RGBA信息作为Mat数据返回给显示组件即可:
/**
* 图像处理都写在此处
*/
@Override
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
//直接返回输入视频预览图的RGBA数据并存在Mat数据中
return inputFrame.rgba();
}
以上操作中,我们在OnCreate函数中已经获取到mCVCamera对象,只有调用mCVCamera.enableView()之后,预览组件才会显示每一帧的Mat图像,但是在显示之前我们必须先确保OpenCV的库文件已经加载完成,所以调用此方法需要进行异步处理:
/**
* 通过OpenCV管理Android服务,异步初始化OpenCV
*/
BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status){
switch (status) {
case LoaderCallbackInterface.SUCCESS:
Log.i(TAG,"OpenCV loaded successfully");
mCVCamera.enableView();
break;
default