Camera2 - 设置AE区域、AF区域和AWB区域的问题。

3
我对camera2还不熟悉,目前已经在Camera2中实现了大部分功能,但我的要求是焦点应该在中间,曝光和白平衡应该基于中间部分进行计算。
为了计算中间区域,我使用了以下方法。
fun getRegion() : MeteringRectangle {
    val sensorRect: Rect = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE)!!
    val sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION)!!

    val regionWidth = 200
    val regionHeight = 200
    var regionLeft: Int = (sensorRect.width() - regionWidth) / 2
    var regionTop: Int = (sensorRect.height() - regionHeight) / 2

    if (sensorOrientation == 90 || sensorOrientation == 270) {
        val temp = regionLeft
        regionLeft = regionTop
        regionTop = temp
    }

    return MeteringRectangle(
        regionLeft,
        regionTop,
        regionWidth,
        regionHeight,
        MeteringRectangle.METERING_WEIGHT_MAX - 1
    )
}

我觉得这个结果很有希望,但由于我是初学者,我真的无法完全理解这个API的整个过程。我尝试像这样设置区域,但没有取得积极的结果,预览图像变得模糊不清。
private fun createPreviewRequest() {
    val previewSurface = Surface(viewFinder.surfaceTexture)

    repeatingRequest = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
    repeatingRequest.addTarget(previewSurface)
    val matArr = getRegion()

    repeatingRequest.apply {
        set(CaptureRequest.CONTROL_AWB_REGIONS, arrayOf(matArr))
        set(CaptureRequest.CONTROL_AF_REGIONS, arrayOf(matArr))
        set(CaptureRequest.CONTROL_AE_REGIONS, arrayOf(matArr))
        set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_AUTO)
        set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO)
        set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON)
        set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH)
    }

    cameraCaptureSession.setRepeatingRequest(repeatingRequest.build(), captureCallBack, cameraHandler)
}

实施我的需求可能需要什么流程?
注意:为了简单起见,我没有对设备是否支持AE、AF、AWB区域进行检查。
1个回答

3

使用Camera2 API

举个当前(2023年)的例子,我建议你看一下{{link1:android/camera-samples/Camera2Extensions,类 java/com/example/android/camera2/extensions/fragments/CameraFragment.kt}},它具有与焦点相关的功能。

例如:

/**
 * Translates a touch event relative to the preview surface to a region relative to the sensor.
 * Note: This operation does not account for zoom / crop and should be handled otherwise the touch
 * point won't correctly map to the sensor.
 */
private fun meteringRectangle(event: MotionEvent): MeteringRectangle {
val sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION)!!
val sensorSize = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE)!!

val halfMeteringRectWidth = (METERING_RECTANGLE_SIZE * sensorSize.width()) / 2
val halfMeteringRectHeight = (METERING_RECTANGLE_SIZE * sensorSize.height()) / 2

// Normalize the [x,y] touch point in the view port to values in the range of [0,1]
val normalizedPoint = floatArrayOf(event.x / previewSize.height, event.y / previewSize.width)

// Scale and rotate the normalized point such that it maps to the sensor region
Matrix().apply {
    postRotate(-sensorOrientation.toFloat(), 0.5f, 0.5f)
    postScale(sensorSize.width().toFloat(), sensorSize.height().toFloat())
    mapPoints(normalizedPoint)
}

val meteringRegion = Rect(
    (normalizedPoint[0] - halfMeteringRectWidth).toInt().coerceIn(0, sensorSize.width()),
    (normalizedPoint[1] - halfMeteringRectHeight).toInt().coerceIn(0, sensorSize.height()),
    (normalizedPoint[0] + halfMeteringRectWidth).toInt().coerceIn(0, sensorSize.width()),
    (normalizedPoint[1] + halfMeteringRectHeight).toInt().coerceIn(0, sensorSize.height())
)

return MeteringRectangle(meteringRegion, MeteringRectangle.METERING_WEIGHT_MAX)
}

private fun startAutoFocus(meteringRectangle: MeteringRectangle) {
submitRequest(
    CameraDevice.TEMPLATE_PREVIEW,
    previewSurface,
    false,
    ) { request ->
        request.apply {
        set(CaptureRequest.CONTROL_AF_REGIONS, arrayOf(meteringRectangle))
        set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO)
        set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START)
        setTag(AUTO_FOCUS_TAG)
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接