跳转至

一、坐标系

1.1 触摸坐标系

Android 的 2D 坐标系如图所示:水平向右为 X 轴正方向,竖直向下为 Y 轴正方向,原点为屏幕左上角 来源。因此竖屏和横屏看视频时,都会自适应转换调整坐标系。

1.2 相机坐标系

坐标原点位于手机横放时的左上角:

坐标系_相机坐标系.png

拍摄的照片是将图像 Sensor 采集到的数据直接存储到 SDCard 上的,同时上传一个方向状态量,显示时基于这个方向状态量来显示 来源

于是 MTK 文件命名时,先显示 x(width, column),后显示 y(height, row)。这个坐标系和 OpenCV 是一致的。

注意:前置显示以 y 为对称轴进行了翻转。

1.3 传感器坐标系

坐标系_传感器坐标系.png

传感器坐标系遵循右手法则。当设备处于默认屏幕方向时,X 轴为水平向右延伸,Y 轴为垂直向上延伸,Z 轴为垂直于屏幕向外延伸。在此坐标系中,屏幕后面的坐标将具有负 Z 值。

  • 比力(specific force):相对于惯性坐标系,作用于单位质量物体上的除引力之外的力。
  • 陀螺(gyro):输出角速度,弧度/秒。
  • 加计(accelerometer):输出比力,米/秒²。

例子

1.4 图像处理的四个坐标系

图像处理与标定会涉及四个坐标系:世界坐标系、相机坐标系、图像坐标系、像素坐标系。四者之间的转换是相机标定的核心(世界→相机经外参旋转平移,相机→图像经透视投影,图像→像素经缩放平移)。

1.5 其他坐标系

芯片坐标系、传感器坐标系、显示屏坐标系、触摸屏坐标系之间也存在转换关系(如芯片坐标系转传感器坐标系、显示屏坐标系转触摸屏坐标系)。

坐标系_芯片转传感器.png

Android Coordinates: Camera, OpenCV in JNI, Canvas

坐标系_坐标转换1.png

坐标系_坐标转换2.png

二、裁切与 CropRegion

2.1 分辨率 Size

  • 标清(< 720p):480×320、640×480(VGA)。
  • 高清:720p、1080i 与 1080p 三种标准形式。
    • 720p:1024×720p
    • 1080i:1920×1080p(隔行扫描),也属于高清
    • 1080P:1920×1080p,又称全高清(Full High Definition)
    • 3MP:2000×1500p
  • 超高清(≥ 4K):4K(3840×2160)、8K(7680×4320)。

VGA 接口最大支持 2048×1536 分辨率、60Hz 刷新率。

2.2 Camera2 crop / zoom 坐标

默认情况下,矩形左上角对应坐标原点:Rect(int left, int top, int right, int bottom)

Camera2 中与坐标/裁切相关的关键 key(参考 Android CameraCharacteristics):

  • SENSOR_INFO_PHYSICAL_SIZE:全像素矩阵的尺寸(宽和高),存储类型 SizeF,单位毫米。
  • SENSOR_INFO_PIXEL_ARRAY_SIZE:全像素阵列的尺寸,可能包括黑色校准像素(black calibration pixels),存储类型 Size,单位像素。
  • SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE:包含在已处理图像格式中的激活像素(active pixels,可接收光照的区域)的矩形区域,坐标基于前者。
  • SENSOR_INFO_ACTIVE_ARRAY_SIZE:如果没有几何畸变校正,该值与前者一致。

裁切/缩放控制(参考 Android CaptureRequest):

  • CONTROL_ZOOM_RATIO:仅支持中心裁切,但支持光学变焦。
  • SCALER_CROP_REGION:支持自由裁切(freedom crop),裁剪倍率 ≥ 1。输出流使用此矩形生成其输出——如果需要,裁剪到较小的区域以保持流的纵横比,然后缩放传感器输入以匹配输出的配置分辨率。

2.3 裁切规则

  • MTK 平台的 SCALER_CROP_REGIONCONTROL_ZOOM_RATIO 应该互斥,否则将出现两次裁切。
  • SCALER_CROP_REGION 基于 active size,active size 一般会比预览的画幅大。
  • crop region 应用于 raw 转其他颜色空间(比如 YUV)时,因此对 raw buffer 不生效。
  • crop region 宽高比 < stream 宽高比时,stream 需要垂直裁切;否则进行水平裁切。

2.4 ROI 应用与 ConvertZoomRatio

APP 目前应该是不支持自由选取 CropRegion。MTK HAL 将 zoom 的修改统一变为具体的坐标。以 zoom=0.617 为例:in: (0 0, 4096, 3072) -> (-953 -953, 6638, 4979)

下式将 CropRegion(MTK_SCALER_CROP_APP_REGIONANDROID_SCALER_CROP_REGION)+ zoom(MTK_CONTROL_ZOOM_RATIO)统一变为 CropRegion(MTK_SCALER_CROP_REGION):

/// ConvertZoomRatio
left   = std::round(left   / zoom_ratio + 0.5f * active_array_dimension.width  * (1.0f - 1.0f / zoom_ratio));
top    = std::round(top    / zoom_ratio + 0.5f * active_array_dimension.height * (1.0f - 1.0f / zoom_ratio));
width  = std::round(width  / zoom_ratio);
height = std::round(height / zoom_ratio);

含义:这是一个以 active array 中心为基准的中心裁切变换。先把矩形尺寸按 \(1/zoom\_ratio\) 缩放(width/zoom_ratio),再把左上角平移到以画面中心为基准的位置——平移量 \(0.5 \cdot W \cdot (1 - 1/zoom\_ratio)\) 正是"为了保持居中"所需的偏移:

  • \(zoom\_ratio > 1\)(放大)时,\(1/zoom\_ratio < 1\),矩形缩小,偏移项为正,矩形向中心收拢;
  • \(zoom\_ratio < 1\)(数字广角)时,矩形放大并超出 active array,左上角坐标变负(如示例中的 -953)。

三、参考