Camera2了解传感器和设备方向

Dud*_*ude 18 android rotation android-camera2

在尝试使用Android Camera2实现触控聚焦功能时,我遇到了一个问题.

理论很简单:

  • 获取预览表面中的拍子位置
  • 将其映射到传感器或传感器裁剪区域的尺寸(如果是缩放),请确保在需要时反转尺寸
  • 应用基础更改以与传感器相同的基础结束
  • MeteringRectangle出来的结果,并在一个新的使用CaptureRequest

有很多例子展示了如何处理第一点和最后一点,但没有多少以可理解的方式处理第二点和第三点.文档和示例并不是很清楚,可能会让人感到困惑.

开始了...


CameraCharacteristics.SENSOR_ORIENTATIONIS形容为

顺时针角度,输出图像需要通过该角度以原始方向旋转到设备屏幕上.

知道传感器坐标系定义为(0,0)是有源像素阵列中的左上角像素,我将其读作将传感器坐标系中捕获的图像旋转到可能产生的位置所需的角度图像在原始方向上看起来很直立.因此,如果传感器的顶部朝向具有纵向原始方向的手机的右侧,SENSOR_ORIENTATION则将为90°. 传感器方向


获得的显示方向mActivity.getWindowManager().getDefaultDisplay().getRotation();记录为:

返回屏幕从"自然"方向的旋转.返回的值可能是Surface.ROTATION_0(无旋转),Surface.ROTATION_90,Surface.ROTATION_180或Surface.ROTATION_270.例如,如果设备具有自然高的屏幕,并且用户将其侧面转向横向,则此处返回的值可以是Surface.ROTATION_90或Surface.ROTATION_270,具体取决于它的转向.角度是屏幕上绘制图形的旋转,这是设备物理旋转的相反方向.例如,如果设备逆时针旋转90度,则补偿渲染将顺时针旋转90度,因此返回的值将为Surface.ROTATION_90.

我发现这个定义比传感器定位更清晰,没有解释的地方.


现在事情开始变得难看......

我决定使用Camera2Raw示例中提供的方法来获取从传感器方向到设备方向的旋转.

/**
 * Rotation need to transform from the camera sensor orientation to the device's current
 * orientation.
 *
 * @param c                 the {@link CameraCharacteristics} to query for the camera sensor
 *                          orientation.
 * @param deviceOrientation the current device orientation relative to the native device
 *                          orientation.
 * @return the total rotation from the sensor orientation to the current device orientation.
 */
private static int sensorToDeviceRotation(CameraCharacteristics c, int deviceOrientation) {
    int sensorOrientation = c.get(CameraCharacteristics.SENSOR_ORIENTATION);

    // Get device orientation in degrees
    deviceOrientation = ORIENTATIONS.get(deviceOrientation);

    // Reverse device orientation for front-facing cameras
    if (c.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) {
        deviceOrientation = -deviceOrientation;
    }

    // Calculate desired JPEG orientation relative to camera orientation to make
    // the image upright relative to the device orientation
    return (sensorOrientation + deviceOrientation + 360) % 360;
}
Run Code Online (Sandbox Code Playgroud)

以下是手机背面和前置摄像头的不同输出表,其中包含纵向原生方向. 在此输入图像描述

我注意到的第一件事是,如果我考虑所描述的输出(从相机传感器方向旋转到设备的当前方向),为了使它有意义,我必须考虑输出旋转是逆时针的(与传感器不同)方向和设备方向)!! 例如,如果我们采用典型的90°传感器和0°设备方向,则重新设置为90°,如果我在分析中没有弄错,则它只能是逆时针方向.

假设我对传感器和设备方向的理解是正确的(不确定),那么上表的结果必定是错误的,因为如果你看一下90°传感器和90°设备方向的情况,它不能是180°它应该是0°.下一张图片直观地展示了我对90°传感器方向电话的所有理解.在此输入图像描述

我继续在R 2中实现我的基础更改,以从屏幕基础到传感器基础获得我的分接点并添加预期的偏移.

我观察到,如果我切换180°和0°计算,那么我的触摸对焦可以完美地工作.从传感器到当前设备方向的旋转的正确观察值实际上对应于前置摄像头的表格.

所以我的直觉sensorToDeviceRotation是有缺陷的,返回值应该是:

// Calculate desired JPEG orientation relative to camera orientation to make
// the image upright relative to the device orientation
return (sensorOrientation - deviceOrientation + 360) % 360;
Run Code Online (Sandbox Code Playgroud)

从计算的内容来看,它实际上更合乎逻辑......

有人能证实吗?或者我在某处误解了什么?

干杯

Edd*_*ala 6

是的,这是Camera2Raw中的错误;感谢您抓住它。

如果您在参考文档中比较Camera#setDisplayOrientation的示例代码,则会看到所需的数学公式

...
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
     result = (info.orientation + degrees) % 360;
     result = (360 - result) % 360;  // compensate the mirror
} else {  // back-facing
     result = (info.orientation - degrees + 360) % 360;
}
Run Code Online (Sandbox Code Playgroud)