2. 基于加速度计数据的旋转补偿
任务说明
在EIS电子防抖中,当设备发生旋转运动时,即使平移抖动已被补偿,画面仍会因旋转而出现模糊。本案例利用加速度计输出的三轴加速度数据,估计设备在俯仰(Pitch)与横滚(Roll)方向上的旋转角度,并据此对图像帧进行反向旋转补偿,以消除旋转造成的画面偏移。
实现方案
核心思路:加速度计在静止或缓慢运动时可视为测量重力矢量。当设备倾斜时,重力在三个轴上的分量发生变化,通过反正切运算即可解算出设备相对水平面的倾斜角(即旋转角)。本案例实现以下功能:
- 读取加速度计三轴原始数据(单位:g);
- 计算Pitch角:
pitch = atan2(-acc_x, sqrt(acc_y² + acc_z²)); - 计算Roll角:
roll = atan2(acc_y, acc_z); - 将角度转换为像素偏移量,对输入图像进行仿射逆变换补偿。
代码实现
import numpy as np
import cv2
def accel_to_rotation(acc_x, acc_y, acc_z):
"""
由加速度计数据计算旋转角(弧度)
输入:三轴加速度值,单位g(重力加速度)
返回:pitch, roll(弧度)
"""
# 防止除零
denom = np.sqrt(acc_y**2 + acc_z**2)
if denom < 1e-6:
denom = 1e-6
pitch = np.arctan2(-acc_x, denom)
roll = np.arctan2(acc_y, acc_z)
return pitch, roll
def rotation_compensate(image, pitch, roll, focal_length=500):
"""
根据旋转角对图像进行反向补偿
image: 输入灰度或BGR图像
pitch, roll: 弧度制旋转角
focal_length: 相机焦距(像素),用于将角度映射为像素位移
"""
h, w = image.shape[:2]
# 角度转像素位移(小角度近似:位移 ≈ 焦距 × 角度)
dx = focal_length * roll
dy = focal_length * pitch
# 构造平移矩阵(反向补偿)
M = np.float32([[1, 0, -dx],
[0, 1, -dy]])
compensated = cv2.warpAffine(image, M, (w, h),
flags=cv2.INTER_LINEAR,
borderMode=cv2.BORDER_REPLICATE)
return compensated
# ===== 样例输入与调用 =====
if __name__ == "__main__":
# 模拟加速度计读数:设备绕X轴倾斜10°,绕Y轴倾斜5°
# 重力矢量在设备坐标系中的投影(单位g)
acc_x = 0.1736 # ≈ sin(10°)
acc_y = 0.0872 # ≈ sin(5°)
acc_z = 0.9848 # ≈ cos(10°)*cos(5°)
pitch, roll = accel_to_rotation(acc_x, acc_y, acc_z)
print(f"Pitch: {np.degrees(pitch):.2f}°, Roll: {np.degrees(roll):.2f}°")
# 生成测试图像(黑色背景上的白色矩形)
img = np.zeros((300, 400), dtype=np.uint8)
cv2.rectangle(img, (100, 80), (250, 200), 255, -1)
# 执行旋转补偿
result = rotation_compensate(img, pitch, roll)
# 保存结果供人工检查
cv2.imwrite("compensated.png", result)
print("补偿图像已保存为 compensated.png")
关键逻辑说明
上述代码中,accel_to_rotation函数利用重力矢量投影关系解算设备姿态角。当设备水平放置时,acc_z≈1g,acc_x≈acc_y≈0,此时pitch和roll均为0;当设备倾斜时,对应轴出现重力分量,角度随之变化。rotation_compensate函数将角度乘以焦距转换为像素位移,并通过仿射平移矩阵实现反向补偿——即图像向旋转的反方向移动,抵消旋转造成的画面偏移。
验证方法
运行方式:在Python环境中安装numpy和opencv-python后直接运行脚本。
判定标准:
- 控制台输出的Pitch角应接近10°,Roll角应接近5°(误差在0.1°以内);
- 打开生成的
compensated.png,观察白色矩形相对原始位置发生了向上和向左的位移(因为pitch为正时dy为正,图像上移;roll为正时dx为正,图像左移),位移量约为500×tan(10°)≈88像素(垂直)和500×tan(5°)≈44像素(水平); - 若将
acc_x和acc_y设为0,则输出角度为0,补偿图像与原始图像完全一致。
边界与限制
本实现基于小角度近似,适用于旋转角小于15°的场景(此时误差小于1%)。当设备存在显著线性加速度时(如剧烈运动),加速度计测得值将包含运动加速度分量,导致角度估计偏差,此时需结合陀螺仪数据(见后续案例)。本案例仅演示旋转补偿核心算法,未包含完整EIS流水线中的平移补偿与边缘裁剪处理。