You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Camera2自定义相机自动对焦缓慢问题优化方案

自动对焦卡顿/耗时过长问题修复方案

你现有代码存在3个直接影响对焦效率的逻辑错误,结合「持机稳定、多帧预览分析」的场景,按以下方式修改即可实现顺滑无拖沓的自动对焦效果:

核心修改点

  • 修正对焦模式选择逻辑:你当前优先选用的FOCUS_MODE_CONTINUOUS_VIDEO是为录像场景设计的,系统会刻意拉长对焦行程、降低对焦触发灵敏度来避免画面跳变,天然对焦速度慢。静态预览/多帧分析场景应该优先选择FOCUS_MODE_CONTINUOUS_PICTURE,该模式下对焦触发灵敏度更高、对焦行程更干脆,不会出现无意义的慢拖效果,仅在设备不支持该模式时再回退到连续视频对焦,最后兜底用普通自动对焦模式。
  • 移除初始化阶段的强制自动曝光锁:你在相机初始化完成时直接锁定AE,会导致对焦过程中曝光参数无法随对焦状态调整,反差式对焦模块拿不到准确的画面对比度数据,很容易出现来回拉风箱、长时间无法合焦的问题。AE锁仅适合在对焦完成、曝光参数收敛后按需开启,不能在初始化阶段直接设置。
  • 补充对焦/测光区域配置:默认对焦区域往往覆盖过大的画面范围,系统会被无关区域的画面干扰判断,拖慢对焦速度。结合多帧分析的场景,直接将对焦、测光区域设置为你实际分析的画面ROI(默认可以设为中心小面积区域),可以大幅缩短合焦时间。
  • 增加对焦状态兜底触发逻辑:部分安卓机型的连续对焦模式在预览持续10-30秒无明显画面变化时会自动暂停对焦触发,很容易出现场景轻微变化后长时间失焦的问题。由于你的场景用户持机稳定,只需要在检测到预览帧对比度/亮度变化超过阈值时,主动触发一次单次对焦即可,不需要频繁触发。

修改后的初始化代码

Camera camera = Camera.open(requestedCameraId);
Camera.Parameters parameters = camera.getParameters();

parameters.setPictureSize(pictureSize.getWidth(), pictureSize.getHeight());
parameters.setPreviewSize(previewSize.getWidth(), previewSize.getHeight());
parameters.setPreviewFpsRange(
        previewFpsRange[Camera.Parameters.PREVIEW_FPS_MIN_INDEX],
        previewFpsRange[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]);
parameters.setPreviewFormat(IMAGE_FORMAT);

// 按优先级选择对焦模式:优先静态预览连续对焦,其次视频连续对焦,最后兜底普通自动对焦
List<String> supportedFocusModes = parameters.getSupportedFocusModes();
if (supportedFocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
} else if (supportedFocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
} else if (supportedFocusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
}

// 配置中心对焦测光区域(可替换为你实际做图像分析的ROI区域)
if (parameters.getMaxNumFocusAreas() > 0) {
    List<Camera.Area> focusAreas = new ArrayList<>();
    // 坐标范围为-1000到1000,中心区域权重设为最高1000
    focusAreas.add(new Camera.Area(new Rect(-150, -150, 150, 150), 1000));
    parameters.setFocusAreas(focusAreas);
}
if (parameters.getMaxNumMeteringAreas() > 0) {
    List<Camera.Area> meteringAreas = new ArrayList<>();
    meteringAreas.add(new Camera.Area(new Rect(-150, -150, 150, 150), 1000));
    parameters.setMeteringAreas(meteringAreas);
}

camera.setParameters(parameters);

// 注册自动对焦回调,合焦后再按需锁定AE/AWB
camera.setAutoFocusMoveCallback(new Camera.AutoFocusMoveCallback() {
    @Override
    public void onAutoFocusMoving(boolean start, Camera camera) {
        Camera.Parameters params = camera.getParameters();
        if (!start) {
            // 对焦停止即合焦完成,此时如果需要固定曝光做图像分析再开AE/AWB锁
            if (params.isAutoExposureLockSupported()) {
                params.setAutoExposureLock(true);
            }
            if (params.isAutoWhiteBalanceLockSupported()) {
                params.setAutoWhiteBalanceLock(true);
            }
        } else {
            // 对焦开始时解锁AE/AWB,保证测光正常
            if (params.isAutoExposureLockSupported()) {
                params.setAutoExposureLock(false);
            }
            if (params.isAutoWhiteBalanceLockSupported()) {
                params.setAutoWhiteBalanceLock(false);
            }
        }
        camera.setParameters(params);
    }
});

场景适配额外优化

因为你的使用场景是用户持机稳定做连续多帧分析,不需要频繁触发对焦:

  • 可以在预览帧回调里计算相邻两帧的灰度方差差,当差值超过阈值(代表场景发生了明显变化,比如拍摄目标移动、光线变化)时,先取消当前对焦,再调用camera.autoFocus(null)触发一次单次对焦即可,避免连续对焦模式频繁无意义触发。
  • 不要在预览过程中反复调用setParameters修改对焦相关参数,部分机型每次调用setParameters都会重启相机硬件流水线,直接导致对焦中断、耗时变长。

内容的提问来源于stack exchange,提问作者Keshav Patidar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 12:31:42