基于无人机正摄JPG图像实现像素GPS定位
原理
- 无人机正摄图采用90度俯仰角,也即相机竖直向下拍摄,假设地面平坦,则相机与地平面可构成相机投影模型
- 从相机参数获取到焦距f,以及物理像平面与图像像平面的转换关系,也即将像素px单位转换为mm单位才能进行物理测量。红外相机可以直接从像元间距获得转换关系,可见光相机可以借助相机标定通过内参获得。
- 从照片exif信息中提取出GPS信息
- 计算出从像平面到地平面物理距离的转换关系ratio=h/f,以及当前位置单位经纬度对应的距离转换关系
- 计算所求像素到中心像素的偏移dx_pix和dy_pix,将偏移从像平面转换到CCD上的物理偏移dx_ccd和dy_ccd,再转换到地面的位置偏移dx_real和dy_real,再通过经纬度和距离的换算关系得到经纬度偏移。
- 根据照片中心经纬度和目标像素经纬度偏移得到最终目标经纬度。
代码
def calculate_pos(center_pix: tuple, center_pos: tuple, height: float, board_corners: np.ndarray) -> (float, float):
focal_length, dist_per_pix = 91e-4, 12e-6 / 2
dist_per_lat, dist_per_lon = 111.31955 * 1e3, 111.31955 * 1e3 * cos(center_pos[1] * pi / 180)
ratio = height / focal_length
board_center = board_corners.mean(0)
dx_pix, dy_pix = board_center[0] - center_pix[0], center_pix[1] - board_center[1]
dx_ccd, dy_ccd = dx_pix * dist_per_pix, dy_pix * dist_per_pix
dx_real, dy_real = dx_ccd * ratio, dy_ccd * ratio
dlon, dlat = dx_real / dist_per_lon, dy_real / dist_per_lat
result = (center_pos[0] + dlon, center_pos[1] + dlat)
return result