赛派号

大疆无人机视觉校准在哪 DJI无人机影像地理坐标系校正

介绍 代码简介

代码的主要功能是将无人机拍摄的图像中的每个像素位置转换为地理坐标(经纬度),并计算图像的实际物理尺寸。具体包括以下几个步骤:

坐标转换:

从图像的像素坐标开始,转换为归一化的图像平面坐标。将这些坐标转换为相机坐标系中的坐标,考虑到焦距的影响。

坐标系转换:

利用无人机的姿态(俯仰角、滚转角、偏航角)将相机坐标系的坐标转换到无人机的世界坐标系。

地理坐标计算:

将世界坐标系中的坐标转换为地理坐标(经纬度)。这里采用简单的地球模型来近似计算地理位置。

物理尺寸计算:

基于图像的分辨率、传感器尺寸和焦距,计算图像的实际物理宽度和高度(以米为单位)。 代码函数

pixel_to_latlon_matrix(image_resolution, camera_params, drone_params): 主要函数,接受图像分辨率、相机参数和无人机参数,返回图像中每个像素的经纬度矩阵以及图像的实际物理宽度和高度。

rotation_matrix(pitch, roll, yaw): 计算给定俯仰角、滚转角和偏航角的旋转矩阵,用于将相机坐标系转换到无人机的世界坐标系。

world_to_latlon_batch(dX, dY, drone_lat, drone_lon): 将世界坐标系的偏移量转换为经纬度的偏移量,基于地球的半径和无人机的当前位置计算。

示例使用 定义了一个示例的相机参数和无人机参数,包括焦距、传感器尺寸、图像分辨率、无人机的经纬度、海拔高度以及姿态角度。通过调用 pixel_to_latlon_matrix 函数计算图像的经纬度矩阵及其物理尺寸,并打印结果。

这段代码适用于将无人机拍摄的高分辨率图像中的每个像素位置准确地映射到地理坐标系中,并提供图像的实际物理尺寸,有助于进行地理信息分析和处理。

代码 import numpy as np def pixel_to_latlon_matrix(image_resolution, camera_params, drone_params): # 创建坐标网格 x_coords, y_coords = np.meshgrid(np.arange(image_resolution[0]), np.arange(image_resolution[1])) # 1. 像素坐标转换为归一化图像平面坐标 x_pixel = (x_coords - image_resolution[0] / 2) * camera_params['sensor_size'][0] / image_resolution[0] y_pixel = (y_coords - image_resolution[1] / 2) * camera_params['sensor_size'][1] / image_resolution[1] # 2. 归一化图像平面坐标转换为相机坐标系 Z_c = camera_params['focal_length'] / 1000 # 转换为米 X_c = x_pixel * Z_c / camera_params['focal_length'] Y_c = y_pixel * Z_c / camera_params['focal_length'] # 3. 相机坐标系转换到无人机的世界坐标系 pitch, roll, yaw = np.radians(drone_params['angles']) R = rotation_matrix(pitch, roll, yaw) world_coords = np.dot(R, np.array([X_c.flatten(), Y_c.flatten(), Z_c * np.ones_like(X_c.flatten())])) # 4. 计算地理坐标系(经纬度) drone_lat = drone_params['latitude'] drone_lon = drone_params['longitude'] latlon_matrix = np.zeros((image_resolution[1], image_resolution[0], 2)) # 利用批量计算的世界坐标 dX = world_coords[0, :].reshape(image_resolution[1], image_resolution[0]) dY = world_coords[1, :].reshape(image_resolution[1], image_resolution[0]) lat, lon = world_to_latlon_batch(dX, dY, drone_lat, drone_lon) latlon_matrix[:, :, 0] = lat latlon_matrix[:, :, 1] = lon # 计算图像的实际物理尺寸 image_width_meters = camera_params['sensor_size'][0] * (image_resolution[0] / camera_params['focal_length']) * 1000 image_height_meters = camera_params['sensor_size'][1] * (image_resolution[1] / camera_params['focal_length']) * 1000 return latlon_matrix, image_width_meters, image_height_meters def rotation_matrix(pitch, roll, yaw): R_x = np.array([ [1, 0, 0], [0, np.cos(roll), -np.sin(roll)], [0, np.sin(roll), np.cos(roll)] ]) R_y = np.array([ [np.cos(pitch), 0, np.sin(pitch)], [0, 1, 0], [-np.sin(pitch), 0, np.cos(pitch)] ]) R_z = np.array([ [np.cos(yaw), -np.sin(yaw), 0], [np.sin(yaw), np.cos(yaw), 0], [0, 0, 1] ]) return np.dot(R_z, np.dot(R_y, R_x)) def world_to_latlon_batch(dX, dY, drone_lat, drone_lon): a = 6378137.0 # Semi-major axis in meters f = 1 / 298.257223563 # Flattening b = a * (1 - f) # Semi-minor axis lat_rad = np.radians(drone_lat) N = a / np.sqrt(1 - (2*f - f**2) * np.sin(lat_rad)**2) m_per_deg_lat = (np.pi / 180) * (a * (1 - f)) / (1 - (2*f - f**2) * np.sin(lat_rad)**2)**1.5 m_per_deg_lon = (np.pi / 180) * (N * np.cos(lat_rad)) delta_lat = dY / m_per_deg_lat delta_lon = dX / m_per_deg_lon object_lat = drone_lat + delta_lat object_lon = drone_lon + delta_lon return object_lat, object_lon # 示例使用 camera_params = { 'focal_length': 24, # in mm 'sensor_size': (36.0, 24.0), # in mm, (width, height) 'image_resolution': (8064, 6048) # in pixels, (width, height) } drone_params = { 'latitude': 40.052235, # degrees 'longitude': 116.243683, # degrees 'altitude': 179, # meters 'angles': (10, 5, 30) # degrees, (pitch, roll, yaw) } latlon_matrix, image_width_meters, image_height_meters = pixel_to_latlon_matrix(camera_params['image_resolution'], camera_params, drone_params) print(f'LatLon Matrix Shape: {latlon_matrix.shape}') print(f'Image Width: {image_width_meters:.2f} meters') print(f'Image Height: {image_height_meters:.2f} meters') 打印结果

LatLon Matrix Shape: (6048, 8064, 2) Image Width: 41.47 meters Image Height: 30.24 meters

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至lsinopec@gmail.com举报,一经查实,本站将立刻删除。

上一篇 没有了

下一篇没有了