OpenCV4 Android 调用摄像头

本文详细介绍了如何在Android设备上使用OpenCV4正确调用摄像头,包括解决黑屏问题的关键步骤,如继承CameraActivity,复写getCameraViewList方法,以及在权限授予后调用setCameraPermissionGranted。同时,提供了使用JavaCamera2View实现拍照功能的示例代码,并讲解了如何修改源码实现全屏预览。

OpenCV4 调用摄像头黑屏问题

OpenCV 调用 Android 摄像头这一块,我之前研究了好几天,都是一片黑,毫无头绪。后来发现 OpenCV4 要想调用摄像头,必须继承自 OpenCV 的 CameraActivity !!!

CameraActivity.java 的源码如下,可以看出大部分代码都是为了 Android M(6.0)以上请求权限而生的,只有两个地方非常关键

  1. protected List<? extends CameraBridgeViewBase> getCameraViewList() { …… }
    子 Activity 在继承 CameraActivity 后,需要复写该函数,把 JavaCamera2View 或 JavaCameraView 送入 List 作为返回值。

  2. cameraBridgeViewBase.setCameraPermissionGranted()
    相机视图初始情况下是黑屏的,即不工作状态。只有当权限授予完毕,调用了 setCameraPermissionGranted 之后,OpenCV 才开始调用相机并把数据输出到 SurfaceView 上。

public class CameraActivity extends Activity {

    private static final int CAMERA_PERMISSION_REQUEST_CODE = 200;

    protected List<? extends CameraBridgeViewBase> getCameraViewList() {
        return new ArrayList<CameraBridgeViewBase>();
    }

    protected void onCameraPermissionGranted() {
        List<? extends CameraBridgeViewBase> cameraViews = getCameraViewList();
        if (cameraViews == null) {
            return;
        }
        for (CameraBridgeViewBase cameraBridgeViewBase: cameraViews) {
            if (cameraBridgeViewBase != null) {
                cameraBridgeViewBase.setCameraPermissionGranted();
            }
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        boolean havePermission = true;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission(CAMERA) != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[]{CAMERA}, CAMERA_PERMISSION_REQUEST_CODE);
                havePermission = false;
            }
        }
        if (havePermission) {
            onCameraPermissionGranted();
        }
    }

    @Override
    @TargetApi(Build.VERSION_CODES.M)
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode == CAMERA_PERMISSION_REQUEST_CODE && grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            onCameraPermissionGranted();
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

实现要领

  1. 首先,要继承 CameraActivity,之前已经说过了。这个基类会去申请权限,然后通知 javaCameraView 已获取到权限,可以正常使用。
  2. 复写父类的 getCameraViewList 方法,将 javaCameraView 回送回去,这样当权限已被赋予时,就可以通知到预览界面开始正常工作了。
  3. OpenCV 已经为我们实现了 Camera 和 Camera2 的函数,如果应用最低版本 minSdkVersion > 5.0,建议使用 JavaCamera2View 的相关函数,否则使用 JavaCameraView。
  4. 在 onResume 时判断 opencv 库是否加载完毕,然后启用预览视图。在 onPause 时由于界面被遮挡,此时应该暂停摄像头的预览以节省手机性能和电量损耗。
  5. 切换前后摄像头时,要先禁用,设置完后启用才会生效。
  6. Camera2 和 Camera 的绝大部分差异 OpenCV 均已经为我们屏蔽在类的内部了,唯一的差别就是两者实现的 CvCameraViewListener 监听器里的预览函数 onCameraFrame 的参数略有不同。从下面的源码可以看出 CvCameraViewListener2 的 inputFrame 由 Mat 类型改为了 CvCameraViewFrame 类型,它额外提供了一个转化为灰度图的接口。

CvCa

评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值