Android Camera高级特性——手动对焦

转自:https://blog.csdn.net/matrix_laboratory/article/details/82871247

Android Camera 系列目录
搭建Camera开发项目
Android Camera API
Camera API使用指南
Camera 高级特性——手动对焦
Android Camera 高级特性——闪光灯、抗闪烁、场景
Camera性能优化
Android Camera2 API
Camera2 API使用指南
Camera2硬件兼容级别
Camera2拉伸问题
Camera2高级特性
Camera2源代码分析
相机模块设计
1. 前言
对焦可以说是相机最基本的功能。
Android Camera提供了多种对焦方式:

FOCUS_MODE_AUTO:个人认为这个名字起的有点随意
FOCUS_MODE_CONTINUOUS_PICTURE : 持续对焦模式,适用于拍照,此模式可调用autoFocus(AutoFocusCallback)
Applications can call autoFocus(AutoFocusCallback) in this mode. If the autofocus is in the middle of scanning, the focus callback will return when it completes. If the autofocus is not scanning, the focus callback will immediately return with a boolean that indicates whether the focus is sharp or not. The apps can then decide if they want to take a picture immediately or to change the focus mode to auto, and run a full autofocus cycle. The focus position is locked after autoFocus call. If applications want to resume the continuous focus, cancelAutoFocus must be called. Restarting the preview will not resume the continuous autofocus. To stop continuous focus, applications should change the focus mode to other modes.1

FOCUS_MODE_CONTINUOUS_VIDEO :持续对焦模式,适用录制视频,对焦比FOCUS_MODE_CONTINUOUS_PICTURE要消极一些,官方文档上说,这是录制视频时最好的选择,因为焦点变化时更加顺滑。此模式可调用autoFocus(AutoFocusCallback)
Since API level 14, applications can call autoFocus(AutoFocusCallback) in this mode. The focus callback will immediately return with a boolean that indicates whether the focus is sharp or not. The focus position is locked after autoFocus call. If applications want to resume the continuous focus, cancelAutoFocus must be called. Restarting the preview will not resume the continuous autofocus. To stop continuous focus, applications should change the focus mode to other modes.

FOCUS_MODE_EDOF : Extended depth of field (EDOF),此模式不能调用autoFocus(AutoFocusCallback)
FOCUS_MODE_FIXED : 适用于超焦距对焦,此模式不能调用autoFocus(AutoFocusCallback)
FOCUS_MODE_INFINITY : 无穷(??)模式,此模式不能调用autoFocus(AutoFocusCallback)
FOCUS_MODE_MACRO :宏观(特写)对焦模式,此模式可调用autoFocus(AutoFocusCallback)
其中前三種是常用的對焦模式。

2. 实现
2.1 默认对焦设置
在前一篇文章《Android Camera API使用指南
》中我提到可以再配置Camera.Parameters中设置对焦类型,这里就不介绍了。

        //对焦方式
        if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
            mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
        }

---------------------

本文来自 微岩 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/matrix_laboratory/article/details/82871064?utm_source=copy 
1
2
3
4
5
6
7
8
2.2 手动对焦实现
2.2.1 最简单的对焦实现
所谓的手动对焦就是用户点击了屏幕的某块区域,需要把相机对焦到用户点击的区域。(又废话了…… -_-||)
一般我们看到文章介绍Camera API1时,通常会说它使用非常简单(当然相对于Camera API2来说),原因是修改Camera的状态非常简单,只要重新配置下Camera.Parameters,然后设置给Camera就OK。最简单的设置步骤是:

    public synchronized void setFocusMode(String focusMode) {

        if (mCameraDevice == null)
            return;

        mParams = mCameraDevice.getParameters();
        List<String> focusModes = mParams.getSupportedFocusModes();
        if (focusModes.contains(focusMode)) {
            mParams.setFocusMode(focusMode);
        }
    }
1
2
3
4
5
6
7
8
9
10
11
上面的对焦实现是非常简单的,切换对焦模式后效果基本没有明显的变化,而且也没有设置对焦区域……(呃~该对焦效果确实生效了…………)

2.2.2 系统相机对焦效果仿真实现
需求分析
首先分析下系统相机的对焦都有哪些效果:

支持用户设置对焦区域,重新设定对焦区域后会触发相机对焦。
重新设定对焦区域后,画面有明显的亮度变化。
第1点很正常,就是预期的对焦效果。
第2点触发图像亮度变化,实际上这已经不是对焦的范畴了,而是测光。从效果上看,系统相机响应手动对焦的同时根据焦点重新测光。

实现方案
通过上面的分析,我们需要设置对焦区域和测光区域,Camera.Parameters中提供了依赖的接口:

getMaxNumFocusAreas:获取支持的对焦区域的个数
setFocusAreas:设置对焦区域列表
getFocusAreas:获取对焦区域列表
getMaxNumMeteringAreas: 获取支持的测光区域的个数
setMeteringAreas:设置测光区域列表
getMeteringAreas:获取测光区域列表
用到的接口就这几个。具体操作如下:

计算对焦和测光区域
Camera中区域是由Camera.Area定义的,用于相机计算自动曝光、自动白平衡、自动聚焦。其中包含两个成员:
    /**
     * Create an area with specified rectangle and weight.
     *
     * @param rect the bounds of the area.
     * @param weight the weight of the area.
     */
    public Area(Rect rect, int weight) {
        this.rect = rect;                    //区域:[-1000, 1000]
        this.weight = weight;            //权重: [1, 1000]
    }

1
2
3
4
5
6
7
8
9
10
11
Area到屏幕的映射如下,坐标(-1000,-1000)代表Camera图像的左上角:


如此就需要把用户点击的屏幕坐标转换为Camera.Area,下面一段简单转换的代码:

            int focusRadius = (int) (radius * 1000.0f);
            int left = (int) (x * 2000.0f - 1000.0f) - focusRadius;
            int top = (int) (y * 2000.0f - 1000.0f) - focusRadius;

            Rect focusArea = new Rect();
            focusArea.left = Math.max(left, -1000);
            focusArea.top = Math.max(top, -1000);
            focusArea.right = Math.min(left + focusRadius, 1000);
            focusArea.bottom = Math.min(top + focusRadius, 1000);
            Camera.Area cameraArea = new Camera.Area(focusArea, 800);
1
2
3
4
5
6
7
8
9
10
添加对焦/测光区域
    List<Camera.Area> meteringAreas;
    List<Camera.Area> focusAreas;
    if (mParams.getMaxNumMeteringAreas() > 0) {
        List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();
        meteringAreas.add(cameraArea);
    }
    if (mParams.getMaxNumMeteringAreas() > 0) {
        focusAreas = new ArrayList<Camera.Area>();
        focusAreas.add(cameraArea);
    }
    mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
    mParams.setFocusAreas(meteringAreas);
1
2
3
4
5
6
7
8
9
10
11
12
设置对焦策略
            try {
                mCameraDevice.cancelAutoFocus();
                mCameraDevice.setParameters(mParams);
                mCameraDevice.autoFocus(callback);
            } catch (Exception e) {
                LogUtil.e(TAG, "Error: focusAtPoint failed: " + e.toString());
            }
1
2
3
4
5
6
7
上面三个步骤都是必须的,对焦不是瞬间完成,而是一个持续的过程。1

cancelAutoFocus:结束上一次的对焦操作,不管是有没有完成对焦
autoFocus:执行一次对焦操作,通过Camera.AutoFocusCallback返回对焦结果。
至此,一次对焦操作就完成了。

3. 参考文献
Android Camera (https://developer.android.com/reference/android/hardware/Camera#autoFocus(android.hardware.Camera.AutoFocusCallback) ↩︎
————————————————
版权声明:本文为CSDN博主「微岩」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/matrix_laboratory/article/details/82871247

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值