一、坐标系¶
1.1 触摸坐标系¶
Android 的 2D 坐标系如图所示:水平向右为 X 轴正方向,竖直向下为 Y 轴正方向,原点为屏幕左上角 来源。因此竖屏和横屏看视频时,都会自适应转换调整坐标系。
1.2 相机坐标系¶
坐标原点位于手机横放时的左上角:
拍摄的照片是将图像 Sensor 采集到的数据直接存储到 SDCard 上的,同时上传一个方向状态量,显示时基于这个方向状态量来显示 来源。
于是 MTK 文件命名时,先显示 x(width, column),后显示 y(height, row)。这个坐标系和 OpenCV 是一致的。
注意:前置显示以 y 为对称轴进行了翻转。
1.3 传感器坐标系¶
传感器坐标系遵循右手法则。当设备处于默认屏幕方向时,X 轴为水平向右延伸,Y 轴为垂直向上延伸,Z 轴为垂直于屏幕向外延伸。在此坐标系中,屏幕后面的坐标将具有负 Z 值。
- 比力(specific force):相对于惯性坐标系,作用于单位质量物体上的除引力之外的力。
- 陀螺(gyro):输出角速度,弧度/秒。
- 加计(accelerometer):输出比力,米/秒²。
1.4 图像处理的四个坐标系¶
图像处理与标定会涉及四个坐标系:世界坐标系、相机坐标系、图像坐标系、像素坐标系。四者之间的转换是相机标定的核心(世界→相机经外参旋转平移,相机→图像经透视投影,图像→像素经缩放平移)。
1.5 其他坐标系¶
芯片坐标系、传感器坐标系、显示屏坐标系、触摸屏坐标系之间也存在转换关系(如芯片坐标系转传感器坐标系、显示屏坐标系转触摸屏坐标系)。
Android Coordinates: Camera, OpenCV in JNI, Canvas
二、裁切与 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_REGION和CONTROL_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_REGION 即 ANDROID_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)。




