【问题标题】:What is the Android Camera2 API equivalent of Camera.Parameters.getHorizontalViewAngle() and Camera.Parameters.getVerticalViewAngle()?什么是相当于 Camera.Parameters.getHorizo​​ntalViewAngle() 和 Camera.Parameters.getVerticalViewAngle() 的 Android Camera2 API?
【发布时间】:2016-10-10 19:29:20
【问题描述】:

这一切都在标题中,但在现已弃用的 Android Camera API 中,有两种方法:Camera.Parameters.getHorizo​​ntalViewAngle() 和 Camera.Parameters.getVerticalViewAngle()。

现在,使用当前的 Camera2 API,文档中似乎没有与这些 API 等效的功能。我假设这是因为 FOV 角度比简单的水平和垂直值更复杂和细微,但我在网上找不到任何关于如何使用较新的 Camera2 API 计算 Android 设备总视野的信息.

【问题讨论】:

    标签: java android camera


    【解决方案1】:

    基本公式是

    FOV.x = 2 * atan(SENSOR_INFO_PHYSICAL_SIZE.x / (2 * LENS_FOCAL_LENGTH))
    FOV.y = 2 * atan(SENSOR_INFO_PHYSICAL_SIZE.y / (2 * LENS_FOCAL_LENGTH))
    

    这是一个approximation,假设是一个理想的镜头等,但通常足够好。

    这会计算整个传感器像素阵列的 FOV。

    但是,给定输出的实际视野会更小;首先,传感器的读出区域通常比全像素阵列小,所以不要直接使用 PHYSICAL_SIZE,您需要先按像素阵列像素数与活动阵列像素数之比(SENSOR_INFO_ACTIVE_ARRAY_SIZE / SENSOR_INFO_PIXEL_ARRAY_SIZE)对其进行缩放.

    然后,视场取决于您配置的输出的纵横比(16:9 FOV 与 4:3 FOV 不同),相对于活动阵列的纵横比,以及裁剪区域的纵横比(数字缩放)(如果它小于完整的活动数组)。

    每个输出缓冲区将是为相应的捕获请求进一步裁剪cropRegion 以达到正确的输出纵横比的结果。 (http://source.android.com/devices/camera/camera3_crop_reprocess.html 有图表)。

    假设我们有一个像素阵列为 (120,120) 的传感器,我们有一个 (10,10)-(110,110) 的活动阵列矩形,因此宽度/高度为 100,100。

    我们配置两个输出,输出A为(40,30),输出B为(50, 50)。让我们将裁剪区域保持在最大值 (0,0)-(100,100)。

    输出 A 和 B 的水平 FOV 将相同,因为最大面积裁剪将导致两个输出都使用完整的活动阵列宽度:

    output_physical_width = SENSOR_INFO_PHYSICAL_SIZE.x * ACTIVE_ARRAY.w / PIXEL_ARRAY.w
    FOV_x = 2 * atan(output_physical_width / (2 * LENS_FOCAL_LENGTH))
    

    但是,垂直 FOV 会有所不同 - 由于纵横比不匹配,输出 A 将仅使用 3/4 的垂直空间:

    active_array_aspect = ACTIVE_ARRAY.w / ACTIVE_ARRAY.h
    output_a_aspect = output_a.w / output_a.h
    output_b_aspect = output_b.w / output_b.h
    output_a_physical_height = SENSOR_INFO_PHYSICAL_SIZE.y * ACTIVE_ARRAY.h / PIXEL_ARRAY.h * output_a_aspect / active_array_aspect
    output_b_physical_height = SENSOR_INFO_PHYSICAL_SIZE.y * ACTIVE_ARRAY.h / PIXEL_ARRAY.h * output_b_aspect / active_array_aspect
    FOV_a_y = 2 * atan(output_a_physical_height / (2 * LENS_FOCAL_LENGTH))
    FOV_b_y = 2 * atan(output_b_physical_height / (2 * LENS_FOCAL_LENGTH))
    

    当输出纵横比

    如果您想计算放大视图的 FOV,请将裁剪区域尺寸/纵横比替换为活动阵列尺寸/纵横比。

    【讨论】:

    • Eddy,这是一个绝妙的回应。非常感谢您抽出宝贵时间仔细而彻底地涵盖如此细致入微(但正确)的主题。它符合我直觉认为的情况,即之前的 Camera API 方法还有很多不足之处,Android 在 Camera2 中排除这种过度简化最终是明智的。干杯!
    • 感谢您的详细解释。当我阅读source.android.com/devices/camera/camera3_crop_reprocess.html 时,它说:如果流的纵横比比裁剪区域宽,则应进一步垂直裁剪流,如果流的纵横比比裁剪区域窄,则应进一步水平裁剪流。这与你在最后一段第二段的评论中所说的相矛盾。根据参考,如果输出纵横比 active,您的代码将起作用。
    • 是的,该示例专门针对提供的数字;例如,它不考虑输出 A 为 (30,40) 的情况,这将导致不同的水平 FOV 和相同的垂直 FOV。
    【解决方案2】:
    private float getHFOV(CameraCharacteristics info) {
        SizeF sensorSize = info.get(CameraCharacteristics.SENSOR_INFO_PHYSICAL_SIZE);
        float[] focalLengths = info.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS);
    
        if (focalLengths != null && focalLengths.length > 0) {
            return (float) (2.0f * atan(sensorSize.getWidth() / (2.0f * focalLengths[0])));
        }
    
        return 1.1f;
    }
    

    【讨论】:

    • 这是否返回弧度值?
    【解决方案3】:

    虽然Eddy Talvala's answer 为您提供了一个解决方案,但该解决方案仅适用于远处的物体。但是,正如https://en.wikipedia.org/wiki/Angle_of_view#Macro_photography 所指出的,对于近距离的拍摄对象,您不能假设镜头和传感器之间的距离等于焦距。这个距离不能查询但可以计算S_2 = S_1 * focal length / (S_1 - focal length)

    在这种情况下,S_1 是当LENS_INFO_FOCUS_DISTANCE_CALIBRATION 不是uncalibrated 时可以从LENS_INFO_MINIMUM_FOCUS_DISTANCE 计算出的最小焦距,在这种情况下LENS_INFO_MINIMUM_FOCUS_DISTANCE 有一个屈光度单位(1/m)。

    所以最终公式变为:

    // focal length/physical size is in mm -> convert from diopter (1/m) to mm
    S_1 = 1000 / LENS_INFO_MINIMUM_FOCUS_DISTANCE
    S_2 = LENS_FOCAL_LENGTH * S_1 / (S_1 - LENS_FOCAL_LENGTH)
    FOV.x = 2 * atan(SENSOR_INFO_PHYSICAL_SIZE.x / (2 * S_2))
    

    我对此进行了测量,并与 Mi 9T Pro 的计算结果进行了比较,结果如下:

    name value
    Focal Length 4.77 mm
    Physical Sensor Size 6,4x4,8 mm
    minimum focus distance 10 diopter
    hyperfocal distance 0.123 diopter
    calculated FOV.y hyperfocal 53.4°
    calculated FOV.y macro 51.2°
    Framesize (y) 9.6 cm
    Distance 10.2 cm
    measured FOV 50.4°

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-02
      • 2017-08-21
      相关资源
      最近更新 更多