原生Camera2的对焦原理和框架,以及代码实现流程

这篇具有很好参考价值的文章主要介绍了原生Camera2的对焦原理和框架,以及代码实现流程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在Android中,Camera2 API提供了对相机硬件的底层访问,包括对焦功能。以下是Camera2对焦原理和框架的简要概述,以及代码实现流程:

对焦原理和框架:

预览: 在开始对焦之前,通常需要先启动相机的预览。预览不仅允许用户看到实时视频流,还可以提供关于相机状态的信息,如对焦模式和当前的对焦区域。
对焦模式: Android支持多种对焦模式,如连续自动对焦(AF-C)、单次自动对焦(AF-S)和手动对焦。每种模式都有不同的应用场景和行为。
对焦区域: 相机可以设置多个对焦区域,每个区域可以独立地对焦。这允许用户选择特定的焦点或自动选择焦点。
触发对焦: 通过API可以手动触发对焦操作,也可以让系统自动触发。一旦触发对焦,相机会尝试调整镜头焦距以实现对焦。
对焦回调: 当对焦完成或发生变化时,系统会发出回调通知。应用程序可以监听这些回调,以便在需要时更新UI或执行其他任务。

代码实现流程:

打开相机: 使用CameraManager获取相机的列表,并选择一个相机打开。
设置预览: 创建一个Surface,用于接收相机的预览输出。将这个Surface与相机预览会话关联起来。
配置相机参数: 通过CameraCharacteristics获取相机的详细信息,并配置必要的参数,如对焦模式和区域。
触发对焦: 使用Camera2 API的方法来触发对焦操作。这通常涉及调用takePicture或startAutofocus方法。
处理回调: 注册一个回调来监听对焦事件。当对焦完成或失败时,可以在这个回调中处理后续逻辑,例如重新触发对焦或显示对焦结果给用户。
清理资源: 在不再需要相机时,确保释放资源并关闭相机连接。

请注意,Camera2 API是一个相对高级的API,需要对Android系统和相机硬件有深入的了解才能有效地使用。此外,由于Android设备众多,不同设备的Camera2实现可能会有所不同。因此,在开发过程中可能需要进行一些特定设备的适配工作。

在Android中,使用原生Camera2 API实现对焦功能需要遵循一系列步骤。下面是一个简化的代码实现过程:

// 导入必要的Camera2 API类  
import android.hardware.camera2.CameraAccessException;  
import android.hardware.camera2.CameraManager;  
import android.hardware.camera2.CameraCharacteristics;  
import android.hardware.camera2.CameraDevice;  
import android.hardware.camera2.CameraMetadata;  
import android.hardware.camera2.CaptureRequest;  
  
// 获取CameraManager实例  
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);  
  
// 获取相机列表和默认相机ID  
String cameraId = manager.getCameraIdList()[0]; // 假设使用默认相机  
  
// 打开相机并获取CameraCharacteristics  
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);  
  
// 创建CaptureRequest.Builder  
CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);  
  
// 设置对焦模式和区域(根据需要配置)  
captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);  
captureBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, regions); // regions是定义的对焦区域  
  
// 开始预览并触发对焦  
try {  
    cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {  
        @Override  
        public void onConfigured(CameraCaptureSession session) {  
            try {  
                session.setRepeatingRequest(captureBuilder.build(), null, null);  
            } catch (CameraAccessException e) {  
                e.printStackTrace();  
            }  
        }  
        @Override  
        public void onConfigureFailed(CameraCaptureSession session) {  
            // 处理配置失败的情况  
        }  
    }, null);  
} catch (CameraAccessException e) {  
    e.printStackTrace();  
}

这段代码提供了一个基本的框架,用于打开相机、设置预览、配置对焦模式和区域,并开始预览和触发对焦。请注意,这是一个简化的示例,实际应用中可能需要处理更多的异常情况、权限请求,以及根据具体需求进行更详细的配置。

现在继续分析原生Camera2对焦代码的实现过程:

首先,在packages\apps\Camera2\src\com\android\camera\one\v2\common\BasicCameraFactory.java文件中构建BasicCameraFactory时会创建初始化自动对焦:

ManualAutoFocusFactory manualAutoFocusFactory = ManualAutoFocusFactory.create(new
                Lifetime(lifetime), frameServer, cameraCommandExecutor, cropRegion,
                sensorOrientation, mPreviewUpdater, requestTemplate,
                templateType, new Settings3A(), Executors.newScheduledThreadPool(1),
                3 /* afHoldSeconds */, cameraCharacteristics.isAutoExposureSupported(),
                cameraCharacteristics.isAutoFocusSupported());
        mManualAutoFocus = manualAutoFocusFactory.provideManualAutoFocus();
        Supplier<MeteringRectangle[]> aeRegions =
                manualAutoFocusFactory.provideAEMeteringRegion();
        Supplier<MeteringRectangle[]> afRegions =
                manualAutoFocusFactory.provideAFMeteringRegion();

        requestTemplate.setParam(CaptureRequest.CONTROL_AE_REGIONS, aeRegions);
        requestTemplate.setParam(CaptureRequest.CONTROL_AF_REGIONS, afRegions);

在看重点,packages\apps\Camera2\src\com\android\camera\one\v2\autofocus\ManualAutoFocusFactory.java

public static ManualAutoFocusFactory create(Lifetime lifetime, FrameServer frameServer,
            CameraCommandExecutor commandExecutor, Supplier<Rect> cropRegion,
            int sensorOrientation,
            Runnable previewRunner, RequestBuilder.Factory rootBuilder,
            int templateType, Settings3A settings3A,
            ScheduledExecutorService threadPool,
            int afHoldSeconds, boolean aeSupport, boolean afSupport) {
        ConcurrentState<MeteringParameters> currentMeteringParameters = new ConcurrentState<>(
                GlobalMeteringParameters.create());
        AEMeteringRegion aeMeteringRegion = new AEMeteringRegion(currentMeteringParameters,
                cropRegion);
        AFMeteringRegion afMeteringRegion = new AFMeteringRegion(currentMeteringParameters,
                cropRegion);

        RequestTemplate afScanRequestBuilder = new RequestTemplate(rootBuilder);
        if (aeSupport) {
            afScanRequestBuilder.setParam(CaptureRequest.CONTROL_AE_REGIONS, aeMeteringRegion);
        }
        if (afSupport) {
            afScanRequestBuilder.setParam(CaptureRequest.CONTROL_AF_REGIONS, afMeteringRegion);
        }

        CameraCommand initialCommand;
        if (afSupport) {
            initialCommand  = new FullAFScanCommand(frameServer, afScanRequestBuilder,
                    templateType);
        } else {
            initialCommand  = new UpdateRequestCommand(frameServer, afScanRequestBuilder,
                    templateType);
        }

        ResettingDelayedExecutor afHoldDelayedExecutor = new ResettingDelayedExecutor(
                threadPool, afHoldSeconds, TimeUnit.SECONDS);
        lifetime.add(afHoldDelayedExecutor);

        CameraCommand afScanHoldResetCommand = new AFScanHoldResetCommand(initialCommand,
                afHoldDelayedExecutor, previewRunner, currentMeteringParameters);

        Runnable afRunner = new ResettingRunnableCameraCommand(commandExecutor,
                afScanHoldResetCommand);

        ManualAutoFocusImpl manualAutoFocus = new ManualAutoFocusImpl(currentMeteringParameters,
                afRunner, sensorOrientation, settings3A);

        return new ManualAutoFocusFactory(manualAutoFocus, aeMeteringRegion, afMeteringRegion);
    }

在这个地方的重点看FullAFScanCommand,packages\apps\Camera2\src\com\android\camera\one\v2\autofocus\FullAFScanCommand.java,这个类里面的run线程里实现对焦的请求。

// Build a request to send a single AF_TRIGGER
            RequestBuilder triggerBuilder = createAFTriggerRequest(afScanResult);
            session.submitRequest(Arrays.asList(triggerBuilder.build()),
                    FrameServer.RequestType.NON_REPEATING);
private RequestBuilder createAFTriggerRequest(AFTriggerResult afScanResult) throws
            CameraAccessException {
        RequestBuilder triggerBuilder = mBuilderFactory.create(mTemplateType);
        triggerBuilder.addResponseListener(forPartialMetadata(afScanResult));
        triggerBuilder.setParam(CaptureRequest.CONTROL_MODE, CaptureRequest
                .CONTROL_MODE_AUTO);
        triggerBuilder.setParam(CaptureRequest.CONTROL_AF_MODE, CaptureRequest
                .CONTROL_AF_MODE_AUTO);
        triggerBuilder.setParam(CaptureRequest.CONTROL_AF_TRIGGER,
                CaptureRequest.CONTROL_AF_TRIGGER_START);
        return triggerBuilder;
    }

这里直接把request下发到cameraservice里实现HAL的调用,实现对焦。

继续看如何实现触摸对焦,在packages\apps\Camera2\src\com\android\camera\CaptureModule.java这里实现触摸对焦的调用:

private void startActiveFocusAt(int viewX, int viewY) {
        if (mCamera == null) {
            // If we receive this after the camera is closed, do nothing.
            return;
        }

        // TODO: make mFocusController final and remove null check.
        if (mFocusController == null) {
            Log.v(TAG, "CaptureModule mFocusController is null!");
            return;
        }
        mFocusController.showActiveFocusAt(viewX, viewY);

        // Normalize coordinates to [0,1] per CameraOne API.
        float points[] = new float[2];
        points[0] = (viewX - mPreviewArea.left) / mPreviewArea.width();
        points[1] = (viewY - mPreviewArea.top) / mPreviewArea.height();

        // Rotate coordinates to portrait orientation per CameraOne API.
        Matrix rotationMatrix = new Matrix();
        rotationMatrix.setRotate(mDisplayRotation, 0.5f, 0.5f);
        rotationMatrix.mapPoints(points);

        // Invert X coordinate on front camera since the display is mirrored.
        if (mCameraCharacteristics.getCameraDirection() == Facing.FRONT) {
            points[0] = 1 - points[0];
        }

        mCamera.triggerFocusAndMeterAtPoint(points[0], points[1]);

        // Log touch (screen coordinates).
        if (mZoomValue == 1f) {
            TouchCoordinate touchCoordinate = new TouchCoordinate(
                    viewX - mPreviewArea.left,
                    viewY - mPreviewArea.top,
                    mPreviewArea.width(),
                    mPreviewArea.height());
            // TODO: Add to logging: duration, rotation.
            UsageStatistics.instance().tapToFocus(touchCoordinate, null);
        }
    }

这个的重点看mCamera.triggerFocusAndMeterAtPoint,最终调用到packages\apps\Camera2\src\com\android\camera\one\v2\autofocus\ManualAutoFocusImpl.java

public void triggerFocusAndMeterAtPoint(float nx, float ny) {
        PointF point = new PointF(nx, ny);
        mMeteringParameters.update(PointMeteringParameters.createForNormalizedCoordinates(
                point /* afPoint */, point /* aePoint */, mSensorOrientation, mSettings3A));
        mAFScanRunnable.run();
    }

这里就可以看到调用到前面讲的自动对焦里去了。

最后,总结一下具体的框图逻辑:

你的鼓励将是我创作的最大动力
原生Camera2的对焦原理和框架,以及代码实现流程,camera hal3框架,数码相机,android文章来源地址https://www.toymoban.com/news/detail-792672.html

到了这里,关于原生Camera2的对焦原理和框架,以及代码实现流程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 十分钟实现 Android Camera2 相机拍照

    因为工作中要使用 Android Camera2 API ,但因为 Camera2 比较复杂,网上资料也比较乱,有一定入门门槛,所以花了几天时间系统研究了下,并在 CSDN 上记录了下,希望能帮助到更多的小伙伴。 上篇文章 我们使用 Camera2 实现了相机预览的功能,这篇文章我们接着上文,来实现 Cam

    2024年02月11日
    浏览(25)
  • Android studio Camera2实现的详细流程

    前提 TextureView.SurfaceTextureListener是一个接口,用于监听TextureView中的SurfaceTexture的状态更改。在使用相机时,您可以使用TextureView来显示相机预览。通过实现SurfaceTextureListener接口,您可以在SurfaceTexture准备好时开始相机预览,并在SurfaceTexture销毁时停止预览。 注意 : 必须是在

    2024年02月05日
    浏览(27)
  • 十分钟实现 Android Camera2 相机预览

    因为工作中要使用 Android Camera2 API ,但因为 Camera2 比较复杂,网上资料也比较乱,有一定入门门槛,所以花了几天时间系统研究了下,并在 CSDN 上记录了下,希望能帮助到更多的小伙伴。 Camera2 API 的包名是 android.hardware.camera2 ,是 Android 5.0 后推出的一套调用摄像头设备的接口

    2024年02月13日
    浏览(24)
  • Android 使用Camera2 API 和 GLSurfaceView实现相机预览

    GLSurfaceView 和 SurfaceView 是 Android 中用于显示图像的两个视图类,它们在实现方式和使用场景上有一些区别。 实现方式:GLSurfaceView 基于 OpenGL ES 技术实现,可以通过 OpenGL ES 渲染图像。而 SurfaceView 则是通过基于线程的绘制方式,可以在独立的线程中进行绘制操作。 性能:由于

    2024年02月09日
    浏览(27)
  • Android 11.0 MTK Camera2 设置默认拍照尺寸功能实现

    在11.0的系统rom定制化开发中,在mtk平台的camera2关于拍照的一些功能修改中,在一些平台默认需要设置最大的分辨率 来作为拍照的分辨率,所以就需要了解拍照尺寸设置流程,然后来实现相关的功能 如图: Camera API中主要涉及以下几个关键类 CameraManager:相机的实际管理者,调

    2024年01月21日
    浏览(30)
  • Android 12.0 MTK Camera2 设置默认拍照尺寸功能实现

    在12.0的系统rom定制化开发中,在mtk平台的camera2关于拍照的一些功能修改中,在一些平台默认需要设置最大的分辨率 来作为拍照的分辨率,所以就需要了解拍照尺寸设置流程,然后来实现相关的功能 如图:

    2024年02月20日
    浏览(34)
  • 安卓camera1设置自动连续对焦

    camera 1实现的控制摄像头拍照功能. adb控制自动拍照,发现近点时拍照很模糊,需要自动连续对焦. mCamera.autoFocus(null) 这个接口只能实现单次对焦.不适用. 作者:帅得不敢出门

    2024年02月14日
    浏览(23)
  • 【Camera2 教程二】Camera2相机打开和关闭接口调用详细说明

    上一章《Camera2教程一》里我们介绍了一些 Camera2 的基础知识,但是并没有涉及太多的 API,从本章开始我们会开发一个具有完整相机功能的应用程序,并且将相机知识分成多个篇章进行介绍,而本章所要介绍的就是相机的开启流程。 阅读本章之后,你将学会以下几个知识点:

    2024年04月25日
    浏览(18)
  • Android Camera2(1)-Camera2在textureView中的预览和拍照

    解释上诉示意图,假如想要同时拍摄两张不同尺寸的图片,并且在拍摄过程中闪光灯必须亮起来。整个拍摄流程如下: 创建一个用于从 Pipeline 获取图片的 CaptureRequest。 修改 CaptureRequest 的闪光灯配置,让闪光灯在拍照过程中亮起来。 创建两个不同尺寸的 Surface 用于接收图片

    2024年02月05日
    浏览(23)
  • 【图像处理】:相机对焦的原理和实现方法

    对焦有三种思路: 也就是观测画面中线条边缘的对比度,对比度最高时即合焦。与此同时,对比度最高也意味着入射光线°形成的每个“点”的能量达到最大,因为合焦即光线完全汇聚,所以即可以通过对比度高低来判断,也可以通过能量大小来判断。但问题就是,焦点在前在

    2024年02月15日
    浏览(20)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包