e8c68a3636d6bde6efe42486b903ee32.png

AF是Camera工作中重要的一部分,是决定画质清晰度的基础,下面来聊聊Android上AF的工作流程。

首先来看一下Android上AF的API,

CONTROL_AF_MODE

设置AF的工作模式

https://developer.android.com/reference/android/hardware/camera2/CaptureRequest?hl=en#CONTROL_AF_MODE

CONTROL_AF_REGIONS

设置AF的对焦区域

https://developer.android.com/reference/android/hardware/camera2/CaptureRequest?hl=en#CONTROL_AF_REGIONS

CONTROL_AF_TRIGGER

触发或取消一次AF

https://developer.android.com/reference/android/hardware/camera2/CaptureRequest?hl=en#CONTROL_AF_TRIGGER

CONTROL_AF_STATE

获取当前AF所处状态

https://developer.android.com/reference/android/hardware/camera2/CaptureResult?hl=en#CONTROL_AF_STATE

Android上AF相关的API大概就这些,接下来详细解释

AF_MODE

  • OFF

相机专业模式中manual focus会设为这个模式,然后APP下发屈光度,底层转换为相应的马达位置,并将lens推到这个位置。目前只有这一个用途。

  • AUTO

字面意思,自动对焦,但实际上准确的应该叫做单次对焦模式,APP下发一次trigger就对焦一次,APP不发trigger的话lens不会移动。

  • MACRO

与AUTO完全一样,暂时不知道有什么用,也没见APP用到过。

  • CONTINUOUS_VIDEO

连续对焦,这个才是真正的全自动对焦,camera画面有场景变化或camera检测到场景失焦,底层会自动触发对焦,保持camera画面处于合焦状态。

  • CONTINUOUS_PICTURE

与CONTINUOUS_VIDEO一样,对于底层两者没有区别。

  • EDOF

Extended depth of field (digital focus) mode. 将lens固定在超焦距位置,没见APP用到过。

目前只需要关注AUTO,CONTINUOUS_VIDEO,CONTINUOUS_PICTURE就足够了,其他基本不会用到。

AF_REGIONS

API1看这里

https://developer.android.com/guide/topics/media/camera?hl=en#metering-focus-areas

API2看这里

https://developer.android.com/reference/android/hardware/camera2/params/MeteringRectangle?hl=en#public-constructors_1

重点说明:

1、只有在AF_MODE_AUTO时才需要配AF_REGIONS,CONTINUOUS_VIDEO和CONTINUOUS_PICTURE模式都不需要,写成null,底层会自动选取画面中心的区域;

2、无论API1还是API2,Camera画面坐标的起始位置都是在手机横屏时(导航栏在右)画面的左上角,跟屏和TP的坐标不一样,需要做转换,APP下发touch AE AF的坐标都要遵循这个原则;

API1坐标示例:

2e68bc84441db9febef3b11ec974bbf3.png

API2坐标示例:

android.sensor.info.activeArraySize.width = 4000;

android.sensor.info.activeArraySize.height = 3000;

为例

public MeteringRectangle (int x,

int y,

int width,

int height,

int meteringWeight)

c46d65c064567fb9aece9d44b249ef09.png

meteringWeight就在0~1000范围内随便写个就行,理论上Android是想支持多点对焦的,奈何很多APP一个对焦框都还没整明白,多点对焦的功能先放放;

3、AF region不能太大也不能太小,在camera画面长宽的10%~20%范围内比较合适。

AF_TRIGGER

  • IDLE

APP不对trigger做处理的话默认为idle。

  • START

Auto mode时AF收到一次CONTROL_AF_TRIGGER_START就开始触发一次对焦,没收到就停在当前位置;

Continuous mode时,收到CONTROL_AF_TRIGGER_START就锁定对焦,停在当前位置,底层场景切换自动触发失效。

  • CANCEL

取消当前对焦动作,等待再次触发。

AF_STATE

AF的几种状态,都是字面意思,不再详细解释,按下拍照按钮时,可以等待scan状态结束再开始拍照,保证拍照时对焦是完成的状态。

  • INACTIVE
  • PASSIVE_SCAN
  • PASSIVE_FOCUSED
  • ACTIVE_SCAN
  • FOCUSED_LOCKED
  • NOT_FOCUSED_LOCKED
  • PASSIVE_UNFOCUSED

各个状态怎么切换,Android官网也解释的很清楚

cf917782dc7f50688f396d2cf96dfd56.png

d570ab735f4d239f7a2e9538f3569ef2.png

不想看也没关系,上状态机

3bfded1656a53b258809d5fe95d89fbd.png

2f6f3fad4b65442280d02b54bb0f74d5.png

红色字体是APP下发的Event,蓝色字体是底层上报的Event,这个状态机图可以比较清楚的看到两种模式下各种event AF状态的切换。

好了,API部分讲完了,下面来讲讲AF正常的整个工作流程,为了方便讲解,只考虑对焦成功的情况。

打开camera

1、拍照模式就设置mode为CONTINUOUS_PICTURE,录像模式设置为CONTINUOUS_VIDEO, 不需要设置AF Region,底层会自动选取画面中心对焦,也不要下发trigger event,底层会依据亮度、Gyro、PD defocus、Laser距离变化等来判断场景是否改变或失焦,检测到场景变化或失焦,会自动触发对焦,保证中心画面一直处于合焦状态;

2、用户Touch camera画面,将mode切换为AUTO,依据Touch的坐标设置AF Region,下发TRIGGER_START,等待对焦完成收到FOCUSED_LOCKED状态,此时Touch AF已完成,AF处于锁定状态;

3、AF锁定3~5s后,APP需要检测Gyro的状态,如果Gyro的值大于一定的阈值后,可以判定用户已经切换场景,需要将AF mode切换回CONTINUOUS_PICTURE或CONTINUOUS_VIDEO;

上图:

ee88b114beeb4b556e8c14423eaa23ac.png

红色是APP需要做的,蓝色是底层自动做的,绿色代表用户的Touch行为,整个过程就是如此简单。

拍照相关的APP,例如美图、无他、Faceu,建议使用这个标准流程,如果只是扫码或其他简单调用相机的功能,只需要将AF mode设为CONTINUOUS_VIDEO,屏蔽掉用户的touch动作,别的什么都不需要做,画面就会是清晰的。

参考代码如下

35c656106fbf8c3f42472e5dec4fcae8.png

举几个例子,看看目前市面上的APP表现的怎么样,

为了更清楚的看到对焦的过程,我把PDAF给关了,只使用Contrast AF。

1、系统自带相机

标准流程,作为其他APP的参考

64M sensor,

android.sensor.info.activeArraySize.width = 9216;

android.sensor.info.activeArraySize.height = 6912;

知乎视频​www.zhihu.com

e2ebf2a6f78e5564f6b15ed4b7f49abc.png

9211b52821cd08bb589e98796aea08ff.png

0fb3550f14230df38c0981e0d2ddf333.png

Tip:系统相机在录像模式,开始录像后再touch的话,即使检测到场景变化也不再切回continuous模式,所以,如果录像的主体距离变化不大的话,可以在开始录像后touch一下主体,或者录像预览时touch主体,等对焦完成后马上开始录像,避免录像过程中触发AF影响画面稳定。

2.FaceU激萌

知乎视频​www.zhihu.com

7f3b038f2fec57793e9143db3c44d407.png

963a20099580a709fa1bc7c1a8a1576a.png

7fe2aa27496f72e63cdc8dc31381512b.png

坐标错了,所以touch狗头没有对上,不清楚APP怎么算的;

Trigger_start下发一次,底层就可以触发一次AF,直到对焦完成。若每一帧都下发,底层需要屏蔽掉对焦过程中的trigger,不屏蔽的话,会导致AF一直处于初始化状态,无法对焦。

3、快手

知乎视频​www.zhihu.com

d938261d52ff9ae0ef75f9d36c280347.png

c5750797668835bf70eb772751d9013c.png

Touch对焦完成后再切换场景没有切回ContinuousVideo mode。

还好,没有什么大问题,值的表扬一下。

4、微信

知乎视频​www.zhihu.com

b340800c6ed628feb09b5c022fa72a00.png

3beff3dbb9f903887c21108dd37555f0.png

不得不吐槽下微信这个万年bug,从我开始做AF就发现这个问题,5年了,还是没改……

只是一个坐标原点位置错了的问题,曾经作为终端厂商联系过微信修改,微信回复改起来太麻烦,不改……

5、美图

知乎视频​www.zhihu.com

90fdbbb9c4e3d77eed681ea26920fb6c.png

其余都正常,用户touch的话坐标正确,region大小合适,touch后切换场景还会切回ContinuousPicture mode,也值的表扬一下。

6、京东

知乎视频​www.zhihu.com

扫码:

a3766790312c0bcf25d7fbeedfd3b143.png

拍照购:

6c6309f83bc175d810272471f694c4d2.png

不得不吐槽一下,这么大个公司,难道没有测试工程师?明显有问题的模块为什么还要上线……

看了这么多APP,只有快手美图这方面做得还可以,虽然不算完美,可能对于APP工程师,AF这块了解的不多,会出现各种各样的错误,希望能以后能改善吧。

我是一名Camera tuning工程师,希望能对Android camera规范化做出一点贡献。

版权所有:

知乎:烫手的洋芋

微博:吃好睡好有福气

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐