> 技术文档 > 无人机图片目标地理位置计算_无人机图像目标定位

无人机图片目标地理位置计算_无人机图像目标定位

因为项目需要,需要通过无人机视频的中的目标位置计算实际的地理坐标位置,一下是计算的方法记录。

1、坐标系定义:

像素坐标系:单位pixel,相机的成像平面,原点在图像的左上方,u轴向右,v轴向下,像素坐标系的单位是像素(pixel),也就是分辨率。
图像坐标系:单位mm,和像素坐标系在同一个平面上,原点是相机光轴与成像平面的交点,通常情况下是成像平面的中点或者叫principal point。单位为物理单位。

机体坐标系:单位m,是以载机位置为原点建立的直角坐标系,X轴指向机头方向,Z轴指向载机垂直向下。即带姿态。
地理坐标系:单位m,以载机位置为原点建立的NED北东地坐标系
大地直角坐标系:单位m,根据参考椭球面建立的笛卡尔直角坐标系,原点为参考椭球面的中心点,Z轴由原点指向地球北极; X轴由原点指向本初子午圈与赤道圈在椭球面上的交点;
WGS84坐标系:与大地直角坐标系一样,只是采用纬度(M)、经度(L)和大地高(H)表示空间中任一点位置。

相机坐标系:单位m,原点是光心,x和y轴与像素坐标系u轴和v轴平行,z轴为相机的光轴。光心到像素平面的距离为焦距f。相机坐标系上的点和成像平面坐标系上的点存在透视投影关系

参考文献:【教程】详解相机模型与坐标转换-CSDN博客

2、像素坐标系 转 图像坐标系

从无人机所拍摄的视频图片的像素坐标系转图片坐标系

    (u,v) 目标点的像素坐标系中的坐标
    (u0,v0) 像素坐标系的中心点
    (dx,dy) 每个像素代表在图像坐标系中的距离 单位mm
    (imageX,imageY) 图像的尺寸 单位像素
    (rx,ry) 目标点在图像中的位置(范围0~1)的比值
 

def pixel_to_image(u,u0,v,v0,dx,dy): x=(u-u0)*dx y=(v-v0)*dy return [x,y]def getPixel(imageX,imageY,rx,ry): return imageX*rx,imageY*ry,imageX/2,imageY/2u,v,u0,v0=getPixel(imageX,imageY,rx,ry)print(u,v,u0,v0)x,y=pixel_to_image(u,u0,v,v0,dx,dy)print(x,y)

3、图像坐标系 转 机体坐标系

    (x,y) 目标点在图像坐标系中的坐标
    H 目标点在机体坐标系中的Z坐标,为相机到目标点实际的高度距离,在这里我们可以使用无人机飞行的相对高度代替(即默认为所有的目标点的海拔高度与无人机起飞的高度一致,如果目标点区域为高低起伏较大的区域,则需要通过dem来缩小误差)
    f 相机的实际焦距(注意,并非相机厂商提供的等效焦距),即相机到成片的距离
 

def image_to_drone(x,y,H,f): Zc=H Xc=Zc/f*x Yc=Zc/f*y return [Xc,Yc,Zc]Xc,Yc,Zc=image_to_drone(x,y,rel_H,f)print(Xc,Yc,Zc)

4、机体坐标系 转 neu地理坐标系

    γ 横滚:北偏东为正
    β 俯仰:抬头为正
    α 航向:右倾斜为正
    (x,y,z) 目标点在机体坐标系中的位置

注意此处计算结果为neu坐标系,需要交换结果的前两个参数转为enu坐标系

def drone_to_neu(α,β,γ,x,y,z): α = np.radians(α) β = np.radians(β) γ = np.radians(γ) C11=np.cos(α)*np.cos(β) C12=np.cos(α)*np.sin(β)*np.sin(γ)-np.sin(α)*np.cos(γ) C13=-np.cos(α)*np.sin(β)*np.cos(γ)-np.sin(α)*np.sin(γ) C21=np.sin(α)*np.cos(β) C22=np.cos(α)*np.cos(γ)+np.sin(α)*np.sin(β)*np.sin(γ) C23=-np.sin(α)*np.sin(β)*np.cos(γ)+np.cos(α)*np.sin(γ) C31=np.sin(β) C32=-np.cos(β)*np.sin(γ) C33=np.cos(β)*np.cos(γ) Ccb=np.array([[C11,C12,C13],[C21,C22,C23],[C31,C32,C33]]) xyz=np.array([x,y,z]) return np.dot(Ccb,xyz)

5、enu坐标系 转 大地直角坐标系

    (lon,lat,H) 无人机的经纬高度
    (x,y,z) 目标点在enu坐标系中的位置

此处的H为无人机的绝对高度,即无人机的海拔高度,与上面的相对高度(无人机起飞的高度)不同。

import pymap3d as pmdef enu_to_ecef(xb,yb,zb,lon,lat,H): return pm.enu2ecef(xb,yb,zb,lat,lon,H)

6、大地直角坐标系:ECEF (EPSG:4978) 转 WGS84 经纬高 (EPSG:4979)

# 定义坐标系:ECEF (EPSG:4978) 转 WGS84 经纬高 (EPSG:4979)\"\"\" 使用 pyproj 将 ECEF 坐标转换为经纬高 (WGS84) 参数: X,Y,Z (单位: 米) 返回: 经度lon(度), 纬度lat(度), 高度h(米)\"\"\"from pyproj import Projfrom pyproj import Transformerdef ecef_to_lla(X,Y,Z): transformer = Transformer.from_crs(\"EPSG:4978\", \"EPSG:4979\", always_xy=True) lon, lat, h = transformer.transform(X,Y,Z) return lon, lat, h

 7、相机物理焦距的计算方法

import mathdef calculate_physical_focal_length(equivalent_focal_length, sensor_width, sensor_height): # 计算传感器的对角线长度 (mm) sensor_diagonal = math.sqrt(sensor_width**2 + sensor_height**2) # 计算裁切系数(Crop Factor) crop_factor = 43.3 / sensor_diagonal # 43.3 是 35mm 全画幅传感器的对角线长度 (mm) # 计算物理焦距 (mm) physical_focal_length = equivalent_focal_length / crop_factor return physical_focal_length, sensor_diagonal, crop_factor# 输入参数equivalent_focal_length = 24 # 等效焦距 (mm)sensor_width = 9.69 # 传感器宽度 (mm)sensor_height = 7.27 # 传感器高度 (mm)# 计算physical_focal_length, sensor_diagonal, crop_factor = calculate_physical_focal_length( equivalent_focal_length, sensor_width, sensor_height)# 输出结果print(f\"传感器对角线: {sensor_diagonal:.2f} mm\")print(f\"裁切系数: {crop_factor:.2f}\")print(f\"物理焦距: {physical_focal_length:.2f} mm\")