嵌入式安卓开发:使用Camera2获取相机

2023-05-16

文章目录

  • Camera2介绍
  • Camera2的主要API类介绍
    • CameraManager
    • 通过CameraManage获取Cameracharacteristics
    • 通过CameraManage获取CameraDevice
    • 从CameraDevice获取CameraCaptureSession
    • 预览效果
  • 参考

Camera2介绍

  • Android 5.0开始,Google 引入了一套全新的相机框架 Camera2(android.hardware.camera2),并且废弃了旧的相机框架 Camera1(android.hardware.Camera)
  • Camera2相比于Camera的API不仅大幅提高了Android系统拍照的功能,还能支持RAW照片输出,甚至允许程序调整相机的对焦模式、曝光模式、快门等。
  • Camera2相比于Camera更加灵活的同时,也更加的复杂,包含的类更多。

Camera2的主要API类介绍

Camera2获取相机涉及的类如下:
在这里插入图片描述

CameraManager

摄像头管理器。这是一个全新的系统管理器,专门用于检测系统摄像头、打开系统摄像头。除此之外,调用CameraManager的getCameracharacteristics(String)方法即可获取指定摄像头的相关特性。代码如下:

	private int mCameraId = CameraCharacteristics.LENS_FACING_FRONT;//后置相机的ID
    String MyCameraIdStr = Integer.toString(mCameraId);
    private CameraManager mCameraManager;   //相机管理者
    private CameraCharacteristics mCameraCharacteristics;   //相机属性
    float EXPOSURE_TIME_RANGE_min_hz = 0, EXPOSURE_TIME_RANGE_max_hz = 0;
    Range EXPOSURE_TIME_RANGE_msg;//相机曝光时间范围,不可改变
    int CameraInfo_FPS_min, CameraInfo_FPS_max;
    Range[] CameraInfo_FPS_Range;
    int CameraInfo_ISO_min, CameraInfo_ISO_max;
    float[] CameraInfo_Aperture;
    float CameraInfo_Focal_Length[];
    boolean FlagOfCreate = false;

	private void CreateCamera() {   //获取CameraManager,得到相机参数
        mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try {
            mCameraCharacteristics = mCameraManager.getCameraCharacteristics(MyCameraIdStr);
            Log.d("曝光补偿范围", mCameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE).toString());
            //上述语句获取相机设备支持的曝光补偿范围
            Log.d("快门时间", mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE).toString());

        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
        FlagOfCreate = true;
        EXPOSURE_TIME_RANGE_msg = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE);
        EXPOSURE_TIME_RANGE_max_hz = (float) (1000000000.0 / (long) EXPOSURE_TIME_RANGE_msg.getLower());
        EXPOSURE_TIME_RANGE_min_hz = (float) (1000000000.0 / (long) EXPOSURE_TIME_RANGE_msg.getUpper());
//        Log.d("测试:",String.format("%d",EXPOSURE_TIME_RANGE_msg.getLower()));
//        CameraInfo_FPS_min = (Range[])(mCameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES))
        CameraInfo_FPS_Range = mCameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
        CameraInfo_FPS_min = (int) CameraInfo_FPS_Range[0].getLower();
        CameraInfo_FPS_max = (int) CameraInfo_FPS_Range[CameraInfo_FPS_Range.length - 1].getUpper();
//        for(int i = 0; i < CameraInfo_FPS_Range.length; ++ i)
//        {
//            Log.d("帧率:",CameraInfo_FPS_Range[i].toString());
//        }
        CameraInfo_ISO_min = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE).getLower();
        CameraInfo_ISO_max = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE).getUpper();

        CameraInfo_Aperture = mCameraCharacteristics.get(CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES);
        CameraInfo_Focal_Length = mCameraCharacteristics.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS);
//
    }
    public void BtnClick_CameraInfo(View v) {
        if (FlagOfCreate != true) {
            CreateCamera();
        }


        String msg = "";
        msg += "快门速度:" + String.format("%.4f,%.4f", EXPOSURE_TIME_RANGE_min_hz, EXPOSURE_TIME_RANGE_max_hz) + "赫兹\n";
        msg += "相机帧率:" + String.format("%d,%d", CameraInfo_FPS_min, CameraInfo_FPS_max) + " fps\n";
        msg += "ISO::" + String.format("%d,%d", CameraInfo_ISO_min, CameraInfo_ISO_max) + "\n";
        msg += "光圈:";
        for (int i = 0; i < CameraInfo_Aperture.length; ++i) {
            msg += String.format("%f,", CameraInfo_Aperture[i]);
        }
        msg += "\n";
        msg += "焦距:";
        for (int i = 0; i < CameraInfo_Focal_Length.length; ++i) {
            msg += String.format("%f,", CameraInfo_Focal_Length[i]);
        }
        msg += "\n";
        TextMsg.setText(msg);

//        Log.d("CameraInfo","WCC");
    }

运行结果如下:
在这里插入图片描述

可以发现相机的光圈只有一个值,即手机的摄像头光圈是固定的,只有一个光圈值。

通过CameraManage获取Cameracharacteristics

摄像头特性。该对象通过CameraManager来获取,用于描述特定摄像头所支持的各种特性。

相比于旧 API 中的 CameraInfo 类。Cameracharacteristics包括:

曝光补偿(Exposure compensation)、
自动曝光/自动对焦/自动白平衡模式(AE / AF / AWB mode)、
自动曝光/自动白平衡锁(AE / AWB lock)、
自动对焦触发器(AF trigger)、
拍摄前自动曝光触发器(Precapture AE trigger)、
测量区域(Metering regions)、
闪光灯触发器(Flash trigger)、
曝光时间(Exposure time)、
感光度(ISO Sensitivity)、
帧间隔(Frame duration)、
镜头对焦距离(Lens focus distance)、
色彩校正矩阵(Color correction matrix)、
JPEG 元数据(JPEG metadata)、
色调映射曲线(Tonemap curve)、
裁剪区域(Crop region)、
目标 FPS 范围(Target FPS range)、
拍摄意图(Capture intent)、
硬件视频防抖(Video stabilization)等。

在上段的例程中,我们展示了通过CameraManage获取CameraCharacteristics,并显示在界面上。
想更详细地了解相关信息,可以参考:
Android Camera2 之 CameraCharacteristics 详解
官方介绍链接

通过CameraManage获取CameraDevice

在最上面的流程图中,CameraManage只是从Context获取摄像头,并进行管理,此时我们可以获取相机的一些参数。如果想进行拍照获取图像,则还需要获取CameraDevice类对象。
CameraDevice通过CameraManage的openCamera方法在回调函数中获取打开的摄像头,具体代码如下:

	CameraDevice.StateCallback MyDeviceCallback; //摄像头监听,在回调中获取camera device
	CameraDevice MyCameraDevice;
	MyDeviceCallback = new CameraDevice.StateCallback() {
    @Override
    public void onOpened(@NonNull CameraDevice camera) {//@NonNull后,便会自动对该参数值进行判空。
        Log.d("Camera调试:", "成功获取Camera Device");
        MyCameraDevice = camera;
        takePreview();//获取Camera device后,从Camera device获取Capture Session
    }

    @Override
    public void onDisconnected(@NonNull CameraDevice camera) {
        Log.d("Camera调试:", "获取Camera Device失败");
    }

    @Override
    public void onError(@NonNull CameraDevice camera, int error) {
        Log.d("Camera调试:", "获取Camera Device错误");
    }
};

首先,我们声明了一个CameraDevice.StateCallback类型的对象,该对象的作用是在执行CameraDevice.OpenCamera方法时,将该回调对象传进去,执行OpenCamera后,会自动地调用该回调函数对象。如下:

	if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
        Log.d("相机调试:", "没有权限");
        return;
    }
    try {
        mCameraManager.openCamera(MyCameraIdStr, MyDeviceCallback, null);
        //打开相机,监听回调,在回调函数中获取camera device
    } catch (CameraAccessException e) {
        Log.e("相机错误:", "打开摄像头失败");
    }

从CameraDevice获取CameraCaptureSession

CameraCaptureSession的作用是控制相机进行预览或者拍照,可以通过CameraDevice的createCaptureSession方法创建,代码如下:

	CameraCaptureSession MyCameraCaptureSession;    //由CameraDvice创建,控制摄像头预览或拍照
	List<Surface> surfaces;
	surfaces = new ArrayList<>();
	surfaces.add(MySurfaceView.getHolder().getSurface());
try {
			/*
             * 参数
             * outputs 相机流输出的地方
             * callback
             * handler 表示 createCaptureSession 代码运行所在的线程,传null,表示运行在当前线程
             */
	MyCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {
   @Override
    public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
        MyCameraCaptureSession = cameraCaptureSession;
        Log.d("MyCameraDevice.createCaptureSession:","成功获取CameraCaptureSession");
    }
    @Override
    public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
        Log.d("MyCameraDevice.createCaptureSession:", "获取camera capture session错误");
    }
}, null);
} catch (CameraAccessException e) {
Log.e("开启预览:", "错误,不能访问摄像头");
}

其中createCaptureSession的第一个参数surfaces是指明预览数据流输出的地方,这里我们从界面上获取一个SurfaceView,将SurfaceView目前的Surface放入List surfaces,作为形参传给createCaptureSession,至此,就可以在界面上看到预览的效果了。

预览效果

如下图所示:
在这里插入图片描述

参考

android camera2 详解说明(一)
Camera2 教程 一概览
Android:Camera2的简单使用
Camera参考详述
camera2使用相机

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

嵌入式安卓开发:使用Camera2获取相机 的相关文章

  • 2021-07-15-2021年全球10大最佳单板计算机开发板(SBC)(第1-3名)

    https www eet china com news 40a12331 html 2021 07 15 2021年全球10大最佳单板计算机开发板 xff08 SBC xff09 xff08 第1 3名 xff09 发布于2021 07
  • ubuntu 显卡

    查看显卡工作状态 lspci grep i vga 我用这个命令只能查出集成显卡 lspci grep NVIDIA xff03 这个能查看N卡的 1 2 rev ff xff09 就表示关闭的状态 利用N卡自带的驱动工具就能一键切换 nv
  • PX4学习(2)——原生固件框架分析

    本文转自阿木社区 xff1a 搭建好了编译环境 xff0c 装上了QT xff0c 就迫不及待的想看看代码的内容 xff0c 结果 一看框架是懵逼的状态 怎么办 xff0c 查阅资料慢慢梳理呗 xff5e 框架分析 xff08 一 xff0
  • 【航模插头总结】 ec3,ec5,t插,xt60,xt90,xt150,as150,mt60,mt30

    在模型接插件行业 xff0c 常用的模型插头无非就是几种 EC2插头 xff0c EC5插头 xff0c EC3插头 xff0c T 插头 xff0c XT60插头 xff0c XT90插头 xff0c XT150插头 xff0c AS15
  • 【算法基础学习 4】互补滤波算法——PX4姿态估计

    目录 应用场景 名词解释 陀螺仪 加速度计 磁力计 xff08 又叫磁罗盘 xff09 坐标系 姿态表示 滤波原理 滤波主要过程 预备知识 预测 校正 加速度计校正 磁力计校正 更新四元数 源码分析 主程序运行流程图 函数功能简述 源码分析
  • 【视觉SLAM之认识摄像头】

    视觉SLAM 了解摄像机单目摄像机双目摄像机 了解摄像机 从这篇文章开始 xff0c 我将用20篇文章带你了解视觉SLAM 我们先来了解一下摄像机 摄像头分为几种 xff0c 分别是 xff1a 单目摄像机双目摄像机深度摄像机 通过一个表格
  • 到底什么是非线性优化?

    你是否也对非线性优化这个领域望而却步 xff1f 你是否也在思索非线性优化求解方法的根源 xff1f 你是否也苦恼于非线性优化到底在研究什么 xff1f 如果你的回答是肯定的 xff0c 说明我们是一样的 那么 xff0c 让我们从这里开始
  • 视线角 视线角速率(待补充)

    视线相对惯性空间的旋转角速度
  • 【无人机学习】惯性导航系统简介

    前面文章SLAM初识 xff08 点击查看 xff09 中我们介绍过SLAM中的两大类传感器 xff1a 激光雷达和视觉传感器 xff0c 并详细分析了其优缺点 而实际上 xff0c 在基于移动机器人的SLAM中 xff0c 还有一类很重要
  • PID介绍 PID调参 串级PID

    鉴于串级PID在pixhawk系统中的重要性 xff0c 无论是误差的补偿 xff0c 如姿态解算 xff1b 还是控制的实现 xff0c 如姿态控制 xff0c 位置控制 xff0c 靠的都是串级的pid xff0c 这里我们先对串级pi
  • 【通俗讲5G】第一次有人把5G讲的这么简单明了

    关于5G通信 xff0c 常见的文章都讲的晦涩难懂 xff0c 不忍往下看 xff0c 特转载一篇 xff0c 用大白话实现5G入门 简单说 xff0c 5G就是第五代通信技术 xff0c 主要特点是波长为毫米级 xff0c 超宽带 xff
  • 终于有人把云计算、大数据和 AI 讲明白了

    原标题 xff1a 不是技术也能看懂云计算 xff0c 大数据 xff0c 人工智能 我今天要讲这三个话题 xff0c 一个是云计算 xff0c 一个大数据 xff0c 一个人工智能 xff0c 我为什么要讲这三个东西呢 xff1f 因为这
  • 常用锁原理的介绍(上)

    本文是学习 多处理器编程的艺术 的笔记 下面主要介绍了一些常用的锁的原理 xff0c 这些只是一些理论 xff0c 离我们实际使用还是有一些差距的 不过这种理论也往往是相对比较好容易理解了掌握的 xff0c 只有了解了这些理论 xff0c
  • 实时数据库数据采集接口API八爪鱼采集接口

    实时数据库数据采集接口是针对国内外各种实时数据库系统 PI IP21等 和DCS PLC等数据源之间的进行实时数据通讯的工具 主要包含IOServer服务器和IOClient客户端两个部分 xff1a IO Server运行在实时数据库服务
  • 实时操作系统的任务调度示例之时间片

    摘要 在之前的一篇博文实时操作系统的任务调度示例之抢占中 xff0c 以实验和代码的形式讲解了不同优先级任务同时出在就绪态中 xff0c 高优先级的任务总是先得到运行 这里就留下了一个问题 xff0c 如果多个出于就绪态的任务具有相同优先级
  • 避障算法之3DVFH+

    目录 一 3DVFH 43 论文翻译 摘要 1 引言 2 相关工作 3 八叉树地图 4 3DVFH 43 4 1 第一步 xff1a 八叉图探索 4 2 第二步 xff1a 二维基础极直方图 2D Primary Polar Histogr
  • linux及C++书籍推荐

    盘点一下今年看的书 xff0c 记录下学习历程也向大家分享一些书籍 xff1a Unix编程3剑客 xff1a RichardSteven的大著 Unix网络编程卷1 xff08 套接字联网api xff09 Unix环境高级编程 Unix
  • 机场跑道检测论文阅读笔记

    机场跑道检测论文阅读笔记 A Robust Vision based Runway Detection and Tracking Algorithm for Automatic UAV Landing 来自沙特的KAUST xff0c 20
  • Jetson AGX Xavier使用笔记

    由于毕设的缘故 xff0c 从业无人机相关 xff0c 嵌入式GPU首选Xavier xff0c 撰文记录一下刷机心得 xff0c 欢迎小伙伴们热烈讨论 xff0c 共同学习 1 刷机 网上教程很多 xff0c 但我依然刷了很久才搞定 xf
  • 稀疏编码SparseNet

    大名鼎鼎的稀疏编码 xff0c 源自1996 记录一下使用sparsenet的心得 0 My Prerequisite Windows10matlab 2016bmingw64 为了节省内存 xff0c 我把matlab2016b装在了移动

随机推荐

  • PX4学习笔记5:数据录制及离线处理

    本文内容主要包括 xff0c rosbag的录制以及消息的离线处理 1 rosbag录制 录制双目相机发布的图片话题如下命令 rosbag record O obs5 bag stereo right image raw stereo le
  • PX4学习笔记3: 速度控制

    记录一下PX4在offboard板外模式下用速度控制四旋翼的过程 参考资料如下 PX4板外模式教程youtube速度控制小实验PX4飞行模式offboard模式offboard模式控制例子 注意 必须2Hz以上的频率发布控制消息 否则PX4
  • 使用matlab将mat矩阵存储为xml文件

    参考链接如下 xff1a 原文 改后 function createxml name1 mat1 name是输入的文件名 xff0c datatest是matlab中的矩阵 一般都是float格式存储的 name2 datatest2 xd
  • Optiver Realized Volatility:Introduction to financial concepts and data - [中文翻译]

    Introduction to financial concepts and data Optiver波动率预测概述评估时间线预测时间线 金融概念与数据介绍订单簿 Order Book 交易 xff08 Trade xff09 做市与市场效
  • 特征工程:tsfresh构造时间序列特征

    本文基本上是对tsfresh官方文档的部分翻译 kaggle上使用可以参考tsfresh features and regression blend Feature extraction settings 对于懒人 xff1a 让我计算一些
  • 港科大VINS-MONO入门(一):框架入门及源码解析

    一 VINS介绍 VINS Mono是HKUST的Shen Shaojie团队开源的一套Visual Inertial融合定位算法 介绍见 https github com HKUST Aerial Robotics VINS Mono 论
  • ROS学习笔记(三):rosrun和runlaunch的用法

    一 区别 rosrun是运行一个单独节点的命令 xff0c 如果要运行多个节点 xff0c 则需要使用多次rosrun命令 roslaunch采用XML的格式对需要运行的节点进行描述 xff0c 可以同时运行多个节点 例如 xff1a lt
  • Javascript>> onmouseover用法

    lt DOCTYPE html gt lt html gt lt head gt lt title gt Window Title lt title gt lt head gt lt body gt lt p gt Test your mo
  • Python之Flask登录认证--before_request

    from flask import Flask render template request Response redirect session url for app 61 Flask name app debug 61 True 自动
  • Prometheus安装部署和node_exporter的使用

    一 环境 服务器IP系统组件192 168 0 181CentOS7 6Prometheus Server 2 18 1192 168 0 182CentOS7 6node exporter 1 0 0 下载地址为 xff1a https
  • easyui 学习总结

    1 分页折行导致显示问题 问题描述 xff1a 1 缩小datagrid的宽度 xff0c 直至分页刚刚折行 2 此时再隐藏pageList按钮和刷新按钮 此时table底部将出现一个白条 39 dg 39 datagrid data ge
  • 机会从来都是留给有准备的人,当然,也总是留给那些耐得住寂寞的人, 在别人玩的时候,静下心来学习

    席华锋 1985年出生 2004年上大学 华中科技大学 2011研究生毕业 工作蚂蚁金服 搞Ocean Base分布式数据库 八年如一日 实现从P5到P8的职业生涯三级跳 xff0c 也完成了三个阶段的成长和蜕变 https blog cs
  • JetsonTX2上安装tensorflow的心酸史

    JetsonTX2上安装tensorflow的心酸史 还是那句话 xff0c 做事情得有耐心 xff0c 有耐心 耐心 心 感觉像是给自己的一个心理暗示 tensorflow安装常见问题总结验证 tensorflow1 3 0安装 好的 x
  • MOS管开关电路应用及MOS管原理、选型

    目录 硬件基础 MOS管原理 使用 开关电路应用0 写在前面 xff1a 1 MOS管基本原理及分类1 1 MOS管分类1 2 MOS管导通原理1 3 MOS管输出特性曲线1 4 MOS管的转移特性1 5 MOS管的寄生二极管 xff1a
  • MQTT服务器搭建和ESP32实现MQTT代码

    文章目录 1 MQTT介绍 xff1a 1 1 需求介绍1 2 MQTT介绍 xff1a 2 具体实现 xff1a 2 1 库推荐2 2 配置MQTT的服务器Broker xff1a 2 3 PubSubClient库使用 xff1a 3
  • 三极管从入门到精通

    文章目录 摘要1 基础1 1 PN结1 2 三极管 2 三极管模拟电路知识2 1 I V特性曲线2 2 极限参数解释2 3 基本共射极放大电路2 4 小信号模型2 5 用小信号模型分析基本共射极放大电路 3 三极管实际模拟电路应用图3 1
  • Type-C接口简单介绍-面向单片机应用

    Type C接口简单介绍 面向单片机应用 1 绪论 用单片机做一些东西时 xff0c Type C接口逐渐替代了MicroUSB接口 但不像MicroUSB那样只有5V GND D 43 D ID五个接口 xff0c Type C接口有24
  • 嵌入式硬件:放大器电路仿真

    文章目录 说明同向放大电路反向放大电路放大器滤波电路低通滤波电路proteus仿真TINA TI仿真 窄带滤波电路preteus仿真TINA TI仿真 参考 说明 书上的放大电路图很多都是理论图 xff0c 和实际应用有所差异 比如下面这个
  • git 切换分支

    1 查看所有分支 git branch a 2 查看当前分支 号表示当前分支 git branch 3 切换分支 git checkout 39 分支名 39 4 修改代码仓库 git remote set url origin 39 仓库
  • 嵌入式安卓开发:使用Camera2获取相机

    文章目录 Camera2介绍Camera2的主要API类介绍CameraManager通过CameraManage获取Cameracharacteristics通过CameraManage获取CameraDevice从CameraDevic