https://www.aliyun.com/jiaocheng/22218.html

    • 阿里云 >  教程中心   >  android教程 >  Camera2点击对焦实现
    • Camera2点击对焦实现
    • 发布时间:2018-01-18 来源:网络 上传者:用户

      关键字: 对焦 Camera2 实现 点击

      发表文章

    • 摘要:android从5.0开始,废弃了原有的Camera接口,提供了全新的Camera2接口。Camera2接口为了给app提供更强大更低级的摄像头控制,将整个的摄像头框架及流程进行了修改。在使用Camera2时,发现手工对焦的实现逻辑与旧的Camera实现该逻辑有较大不同,本文就谈下如何使用Camera2进行手工对焦。1.操作摄像头进行对焦mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_REGIONS,newMeteri
    • android从5.0开始,废弃了原有的Camera接口,提供了全新的Camera2接口。Camera2接口为了给app提供更强大更低级的摄像头控制,将整个的摄像头框架及流程进行了修改。在使用Camera2时,发现手工对焦的实现逻辑与旧的Camera实现该逻辑有较大不同,本文就谈下如何使用Camera2进行手工对焦。

      1. 操作摄像头进行对焦 
      mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, new MeteringRectangle[] {new MeteringRectangle(rect, 1000)}); 
      mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_REGIONS, new MeteringRectangle[] {new MeteringRectangle(rect, 1000)}); 
      mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO); 
      mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START); 
      mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CameraMetadata.CONTROL_AE_PRECAPTURE_TRIGGER_START); 
      mPreviewRequest = mPreviewRequestBuilder.build(); 
      try { 
      mCaptureSession.setRepeatingRequest(mPreviewRequest, mAfCaptureCallback, mBackgroundHandler); 
      } catch (CameraAccessException e) { 
      Log.e(TAG, "setRepeatingRequest failed, " + e.getMessage()); 
      }

      主要步骤:

      指定自动对焦和自动嚗光测量的区域,这个区域就是手指点击的图像区域。 
      指定自动对焦模式为 CONTROL_AF_MODE_AUTO 模式,非点击对焦的时候,模式应该为CONTROL_AF_MODE_CONTINUOUS_PICTURE 或者 CONTROL_AF_MODE_CONTINUOUS_VIDEO。 
      将对焦的状态修改为开始对焦 
      触发连续获取图像数据 
      2. 对焦完成恢复正常的预览模式 
      if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState 
      || CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) { 
      mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL); 
      mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO); 
      mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON); 
      mPreviewRequest = mPreviewRequestBuilder.build(); 
      try { 
      mCaptureSession.setRepeatingRequest(mPreviewRequest, null, mBackgroundHandler); 
      } catch (CameraAccessException e) { 
      Log.e(TAG, "setRepeatingRequest failed, errMsg: " + e.getMessage()); 

      }

      点击对焦完成后,将对焦模式修改为 CONTROL_AF_MODE_CONTINUOUS_VIDEO。

      3. 计算自动对焦区域

      CONTROL_AF_REGIONS 的参数是指定用来测量对焦的区域,摄像头设备使用这个区域来测量光度情况进行对焦,因此该区域坐标系基于摄像头成像区域的坐标系。那么app接收到的图像数据与成像区域的关系如何呢?

      手机摄像头成像区域是固定的,因此系统对于app中需要采集不同分辨率的需求做法是:将成像区域按照需要的分辨率比例进行居中裁剪,然后缩放到对应的尺寸。

      Camera2通过不同的接口,给应用层提供了这方面的信息:

      SENSOR_INFO_PIXEL_ARRAY_SIZE 表示的是摄像头成像区域所使用的内存大小。 
      SENSOR_INFO_ACTIVE_ARRAY_SIZE 表示真正接收光线的区域,因此成像的区域是该参数指定的区域,当然该矩形区域的坐标系基于SENSOR_INFO_PIXEL_ARRAY_SIZE 。 
      SCALER_CROP_REGION 表示最终的输出内容是基于 SENSOR_INFO_ACTIVE_ARRAY_SIZE 裁剪的部分,而该值指定裁剪的区域。

       
      摄像头输出裁剪区域

      如图:整个区域(2000 x 1500)是整个成像所使用的内存区域,蓝色部分(crop region)是输出内容是使用的裁剪区域(根据我的测试结果发现,crop region基本等于成像区域大小),绿色的和橘黄色的部分就是不同分辨率所使用的区域。

      了解该裁剪流程之后,就可以知道如何计算对焦区域了:

      一般app拿到摄像头来的数据之后,会将摄像头进行合适的旋转,然后根据屏幕比例居中裁剪图像数据,再进行显示。所以我们先将屏幕上面点击区域的坐标转化为app收到的图像区域的坐标: 
      // 先取相对于view上面的坐标 
      double x = event.getX(), y = event.getY(), tmp; 
      // 取出来的图像如果有旋转角度的话,则需要将宽高交换下 
      int realPreviewWidth = mPreviewSize.width, realPreviewHeight = mPreviewSize.height; 
      if (90 == mDisplayRotate || 270 == mDisplayRotate) { 
      realPreviewWidth = mPreviewSize.height; 
      realPreviewHeight = mPreviewSize.width; 

      // 计算摄像头取出的图像相对于view放大了多少,以及有多少偏移 
      double imgScale = 1.0, verticalOffset = 0, horizontalOffset = 0; 
      if (realPreviewHeight * viewWidth > realPreviewWidth * viewHeight) { 
      imgScale = viewWidth * 1.0 / realPreviewWidth; 
      verticalOffset = (realPreviewHeight - viewHeight / imgScale) / 2; 
      } else { 
      imgScale = viewHeight * 1.0 / realPreviewHeight; 
      horizontalOffset = (realPreviewWidth - viewWidth / imgScale) / 2; 

      // 将点击的坐标转换为图像上的坐标 
      x = x / imgScale + horizontalOffset; 
      y = y / imgScale + verticalOffset; 
      if (90 == mDisplayRotate) { 
      tmp = x; x = y; y = mPreviewSize.height - tmp; 
      } else if (270 == mDisplayRotate) { 
      tmp = x; x = mPreviewSize.width - y; y = tmp; 

      app取到的图像是按照裁剪区域(crop region)按照预览尺寸的比例进行居中裁剪的,所以需要计算app取到的图像相对于裁剪区域进行了多少缩放,以及有多少位移: 
      // 计算取到的图像相对于裁剪区域的缩放系数,以及位移 
      Rect cropRegion = mPreviewRequest.get(CaptureRequest.SCALER_CROP_REGION); 
      if (null == cropRegion) { 
      Log.e(TAG, "can't get crop region"); 
      cropRegion = mActiveArraySize; 

      int cropWidth = cropRegion.width(), cropHeight = cropRegion.height(); 
      if (mPreviewSize.height * cropWidth > mPreviewSize.width * cropHeight) { 
      imgScale = cropHeight * 1.0 / mPreviewSize.height; 
      verticalOffset = 0; 
      horizontalOffset = (cropWidth - imgScale * mPreviewSize.width) / 2; 
      } else { 
      imgScale = cropWidth * 1.0 / mPreviewSize.width; 
      horizontalOffset = 0; 
      verticalOffset = (cropHeight - imgScale * mPreviewSize.height) / 2; 

      将点击区域相对于app取到的图像坐标,转化为相对于成像区域的坐标: 
      // 将点击区域相对于图像的坐标,转化为相对于成像区域的坐标 
      x = x * imgScale + horizontalOffset + cropRegion.left; 
      y = y * imgScale + verticalOffset + cropRegion.top; 
      按照对焦区域为成像区域的0.1倍计算对焦的矩形: 
      double tapAreaRatio = 0.1; 
      Rect rect = new Rect(); 
      rect.left = clamp((int) (x - tapAreaRatio / 2 * cropRegion.width()), 0, cropRegion.width()); 
      rect.right = clamp((int) (x + tapAreaRatio / 2 * cropRegion.width()), 0, cropRegion.width()); 
      rect.top = clamp((int) (y - tapAreaRatio / 2 * cropRegion.height()), 0, cropRegion.height()); 
      rect.bottom = clamp((int) (y + tapAreaRatio / 2 * cropRegion.height()), 0, cropRegion.height()); 
      4. 总结

      Camera2相对于就的Camera api来说,使用复杂度提升不少,但是提供更多的操作空间。同时,由于从Android 5.0就开始提供Camera2的接口,而有些机器并不一定支持全部的Camera2特性,所以需要通过 android.info.supportedHardwareLevel 查询支持的程度:

      LEGACY:app调用Camera2的接口时,由框架将其转调给Camera API1来实现对应的功能,因此不支持Camera2的某些特性,如:每帧控制。 
      FULL:设备支持所有的Camera2接口。 
      LIMITED:设备支持部分的Camera2接口。

      demo地址在这,demo中并没有查询级别,如果demo跑得不正常时,可以检查下支持级别是否是FULL。

      文中的理解来自于下面几篇文章,有任何问题,欢迎指教:

      http://source.android.com/devices/camera/camera3_crop_reprocess.html 
      https://developer.android.com/reference/android/hardware/camera2/CaptureRequest.html#SCALER_CROP_REGION 
      https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#SENSOR_INFO_ACTIVE_ARRAY_SIZE
      https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#SENSOR_INFO_PIXEL_ARRAY_SIZE

    • 以上是

Camera2点击对焦实现

      的内容,更多

对焦Camera2实现点击

      的内容,请您使用右上方搜索功能获取相关信息。

    • 上一篇 1 2 3 4 下一篇
    • 本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果你发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:zixun-group@service.aliyun.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。
    • 相关文章

Camera2点击对焦实现2的更多相关文章

  1. Camera2点击对焦实现

    https://www.jianshu.com/p/76225ac72b56 android从5.0开始,废弃了原有的Camera接口,提供了全新的Camera2接口.Camera2接口为了给app提 ...

  2. Android JetPack组件-CameraX初探

    CameraX 又是一个 Google 推出的 JetPack 组件 ,是一个新鲜玩意儿,故给大家分享下我在项目中的使用过程心得.. CameraX 是什么? Google 开发者文档 对 Camer ...

  3. AF引起的camera偶现卡顿问题

    相关log如下: 01-01 08:04:26.299 867 3220 E Camera2Client: syncWithDevice: Camera 0: Timed out waiting sy ...

  4. 如何取消 UIView 动画?

    原文链接 最近项目中有一个需求是需要手动点击相机对焦,这里由于相机对焦部分需要一个类似于系统对焦框一样的缩放动画,同时动画时长为0.3秒,因此这里就有一个很普遍的需求,如果用户在0.3秒内继续点击对焦 ...

  5. Android Camera2 拍照(四)——对焦模式

    原文:Android Camera2 拍照(四)--对焦模式 本篇将重点介绍使用Camera2 API进行手动对焦的设置,以及在手动对焦与自动对焦模式之间切换. 一.手动对焦响应事件 首先我们要实现点 ...

  6. Vuforia点击屏幕自动对焦,过滤UGUI的按钮

    //点击屏幕自对对焦 #if UNITY_EDITOR )) #elif UNITY_ANDROID || UNITY_IPHONE && Input.GetTouch().phase ...

  7. 荣品RP4412开发板摄像头驱动调用及对焦控制

    1.关于更换不同摄像头驱动调用问题. 问:RP4412开发板,我用的摄像头640*480图像预览时OK的,但是我调用1280*720的初始化预览,摄像头没有图像了,是不是camera程序也需要修改? ...

  8. adb 命令模拟按键事件 模拟 点击 事件

    有时我们需要程序模拟按钮或点击,而手机本身又没有,哪么可以采取adb 模拟实现,最后再去实际设备去测试(前期一般都拿不到设备): 如模拟上一首,下一首,暂停等,手机上是没有的,但有些设备上是有的: / ...

  9. 【转】[Android编程心得] Camera(OpenCV)自动对焦和触摸对焦的实现

    参考http://stackoverflow.com/questions/18460647/android-setfocusarea-and-auto-focus http://blog.csdn.n ...

随机推荐

  1. Kinect2.0相机标定

    尝试进行Kinect2.0相机进行标定 1. Color镜头标定 $(u_{rgb},v_{rgb},1)=W_{rgb}*(x,y,z)$ Calibration results after opt ...

  2. Android使得Fragment 切换时不重新实例化

    以前实现Fragment的切换都是用replace方法实现 public void startFragmentAdd(Fragment fragment) { FragmentManager frag ...

  3. docker容器多服务(不推荐)

    1.最常用方式配置进程管理工具Supervisor 2.最简单的就是把多个启动命令放到一个启动脚本里面,启动的时候直接启动这个脚本 第一种方式: 1.构建基础镜像 FROM lmurawsk/pyth ...

  4. iOS库

    https://medium.com/app-coder-io/33-ios-open-source-libraries-that-will-dominate-2017-4762cf3ce449#.i ...

  5. CentOS6.5安装kafka-2.10-0.8.2(单机)

    1.下载 地址:https://kafka.apache.org/downloads 本文中下载版本:kafka_2.10-0.8.2.2.tgz 2.安装 安装目录:/usr/local [root ...

  6. 懒汉处理dapper字段名与属性名的映射方式

    你还以为走路是世上最简单的事情呢?只不过是把一只脚放到另一只脚前面.但我一直很惊讶这些原本是本能的事情实际上做起来有多困难.而吃,吃也是一样的,有些人吃起东西来可困难了.说话也是,还有爱.这些东西都可 ...

  7. template.js简单入门

    template.js是一款开源的JavaScript模板引擎,用来渲染页面的. github地址 https://github.com/yanhaijing/template.js 下载templa ...

  8. bat cmd 删除文件或文件夹 删除注册表

    @echo off rd "C:\Documents and Settings\Administrator\桌面\新建文件夹" del 是用来删除文件的,删除文件夹的命令是rd 注 ...

  9. Visual Studio快捷键查询

    Ctrl+E,D —-格式化全部代码  Ctrl+E,F —-格式化选中的代码  CTRL + SHIFT + B生成解决方案  CTRL + F7 生成编译  CTRL + O 打开文件  CTRL ...

  10. 《大话设计模式》c++实现 建造者模式

    一.UML图 关键词:Subject维护一个Observer列表,Subject执行Notify()时就执行列表中的每个Observer的Update(). 二.概念 观察者模式:定义了一种一对多的依 ...