航拍无人机像素坐标转世界坐标
一、背景
已知相机参数(传感器宽度和高度、图像宽度和高度、焦距、相对航高、像主点坐标 ),在给定像素坐标的前提下,求世界坐标,大部分通过AI来实现,不知道哪个步骤有问题,望大家指正
二、代码
import numpy as np
import cv2
# 畸变校正
def undistort_pixel(pixel_x, pixel_y, sym_dist, dec_dist):
k0,k1,k2,k3=sym_dist
# k1, k2, p1, p2, k3 = sym_dist
p1,p2,p3=dec_dist
fx = focal_length_mm
fy = focal_length_mm
cx = xpoff_px
cy = ypoff_px
distCoeffs = np.array([k1, k2, p1, p2,k3])
cameraMatrix = np.array([[fx, 0, cx], [0, fy, cy], [0, 0, 1]])
distorted_points = np.array([[pixel_x, pixel_y]], dtype=np.float32)
undistorted_points = cv2.undistortPoints(distorted_points, cameraMatrix, distCoeffs)
#################################################### 4\对图像去畸变
img = cv2.imread('./images/100_0004_0001.JPG')
img_undistored = cv2.undistort(img, cameraMatrix, distCoeffs)
cv2.imwrite('./images/100_0004_00011.JPG', img_undistored)
return undistorted_points[0][0][0], undistorted_points[0][0][1]
# 相机坐标转世界坐标
def camera_to_world_coordinates(cam_coords, pos):
# 获取相机到世界的转换参数
pos_x, pos_y, pos_z, roll, pitch, yaw = pos
# 将角度转换为弧度
roll = np.radians(roll)
pitch = np.radians(pitch)
yaw = np.radians(yaw)
# 计算旋转矩阵
R_roll = np.array([
[1, 0, 0],
[0, np.cos(roll), -np.sin(roll)],
[0, np.sin(roll), np.cos(roll)]
])
R_pitch = np.array([
[np.cos(pitch), 0, np.sin(pitch)],
[0, 1, 0],
[-np.sin(pitch), 0, np.cos(pitch)]
])
R_yaw = np.array([
[np.cos(yaw), -np.sin(yaw), 0],
[np.sin(yaw), np.cos(yaw), 0],
[0, 0, 1]
])
R = R_yaw @ R_pitch @ R_roll
# 相机坐标转换到世界坐标
cam_coords_homogeneous = np.array([cam_coords[0], cam_coords[1], -H, 1])
world_coords = R @ cam_coords_homogeneous[:3] + np.array([pos_x, pos_y, pos_z])
return world_coords
if __name__ == "__main__":
取消
首页
编程
手机
软件
硬件
安卓
苹果
手游
教程
平面
服务器
首页 > 脚本专栏 > python > python无人机航拍图片像素坐标
python实现无人机航拍图片像素坐标转世界坐标的示例代码
2024-06-12 10:42:38 作者:GIS从业者
已知相机参数在给定像素坐标的前提下,求世界坐标,大部分通过AI来实现,本文给大家分享实现脚本,感兴趣的朋友跟随小编一起看看吧
背景
已知相机参数(传感器宽度和高度、图像宽度和高度、焦距、相对航高、像主点坐标 ),在给定像素坐标的前提下,求世界坐标,大部分通过AI来实现,不知道哪个步骤有问题,望大家指正
脚本
import numpy as np
import cv2
# 畸变校正
def undistort_pixel(pixel_x, pixel_y, sym_dist, dec_dist):
k0,k1,k2,k3=sym_dist
# k1, k2, p1, p2, k3 = sym_dist
p1,p2,p3=dec_dist
fx = focal_length_mm
fy = focal_length_mm
cx = xpoff_px
cy = ypoff_px
distCoeffs = np.array([k1, k2, p1, p2,k3])
cameraMatrix = np.array([[fx, 0, cx], [0, fy, cy], [0, 0, 1]])
distorted_points = np.array([[pixel_x, pixel_y]], dtype=np.float32)
undistorted_points = cv2.undistortPoints(distorted_points, cameraMatrix, distCoeffs)
#################################################### 4\对图像去畸变
img = cv2.imread('./images/100_0004_0001.JPG')
img_undistored = cv2.undistort(img, cameraMatrix, distCoeffs)
cv2.imwrite('./images/100_0004_00011.JPG', img_undistored)
return undistorted_points[0][0][0], undistorted_points[0][0][1]
# 相机坐标转世界坐标
def camera_to_world_coordinates(cam_coords, pos):
# 获取相机到世界的转换参数
pos_x, pos_y, pos_z, roll, pitch, yaw = pos
# 将角度转换为弧度
roll = np.radians(roll)
pitch = np.radians(pitch)
yaw = np.radians(yaw)
# 计算旋转矩阵
R_roll = np.array([
[1, 0, 0],
[0, np.cos(roll), -np.sin(roll)],
[0, np.sin(roll), np.cos(roll)]
])
R_pitch = np.array([
[np.cos(pitch), 0, np.sin(pitch)],
[0, 1, 0],
[-np.sin(pitch), 0, np.cos(pitch)]
])
R_yaw = np.array([
[np.cos(yaw), -np.sin(yaw), 0],
[np.sin(yaw), np.cos(yaw), 0],
[0, 0, 1]
])
R = R_yaw @ R_pitch @ R_roll
# 相机坐标转换到世界坐标
cam_coords_homogeneous = np.array([cam_coords[0], cam_coords[1], -H, 1])
world_coords = R @ cam_coords_homogeneous[:3] + np.array([pos_x, pos_y, pos_z])
return world_coords
if __name__ == "__main__":
####################################################基本参数
# 传感器宽度和高度(毫米)
sensor_width_mm = 12.83331744000000007588
sensor_height_mm = 8.55554496000000064271
# 图像宽度和高度(像素)
image_width_px = 5472
image_height_px = 3648
# 焦距(毫米)
focal_length_mm = 8.69244671863242679422
# 焦距(米)
focal_length_m = 8.69244671863242679422/1000
# 相对航高(米)
H=86.93
#像主点坐标 (像素)
xpoff_px=20.88973563438230485190
ypoff_px=50.51977022866981315019
#################################################### 1\计算空间分辨率
# 传感器尺寸转换为米
sensor_width_m = sensor_width_mm / 1000
sensor_height_m = sensor_height_mm / 1000
# 计算水平和垂直的 GSD
GSD_x = (sensor_width_m/image_width_px) * (H / focal_length_m )
GSD_y = (sensor_height_m /image_height_px) * (H / focal_length_m)
# 水平和垂直方向的 GSD
print("水平方向的 GSD:", GSD_x, "米/像素")
print("垂直方向的 GSD:", GSD_y, "米/像素")
#################################################### 2\给定像素坐标,计算相机坐标
# 像素坐标
oripixel_x = image_width_px
oripixel_y = image_height_px
# oripixel_x = image_width_px/2
# oripixel_y = image_height_px/2
# oripixel_x = 0
# oripixel_y = 0
pixel_x=oripixel_x-xpoff_px-image_width_px/2
pixel_y=oripixel_y-ypoff_px-image_height_px/2
# 计算相机坐标(假设无畸变)
camera_x = pixel_x * GSD_x
camera_y = pixel_y * GSD_y
print("像素坐标 (", oripixel_x, ",", oripixel_y, ") 对应的相机坐标 (x, y): (", camera_x, "米, ", camera_y, "米)")
#################################################### 3\计算畸变后坐标
# 对称畸变系数
sym_dist = [0, -0.00043396118129128110, 0.00000262222711982075, -0.00000001047488706013]
# 径向畸变
dec_dist = [0.00000205885592671873, -0.00000321714140091248, 0]
# 进行畸变校正
undistorted_camera_x, undistorted_camera_y = undistort_pixel(pixel_x, pixel_y, sym_dist, dec_dist)
print("畸变校正后像素坐标 (", oripixel_x, ",", oripixel_y, ") 对应的相机坐标 (x, y): (", undistorted_camera_x, "米, ", undistorted_camera_y, "米)")
#################################################### 4\计算世界坐标
# POS数据
pos = [433452.054688, 2881728.519704, 183.789696, 0.648220, -0.226028, 14.490357]
# 计算世界坐标
world_coords = camera_to_world_coordinates((undistorted_camera_x, undistorted_camera_y), pos)
print("旋转平移变换后像素坐标 (", oripixel_x, ",", oripixel_y, ") 对应的世界坐标 (x, y): (", world_coords[0], "米, ", world_coords[1], "米)")
到此这篇关于python实现无人机航拍图片像素坐标转世界坐标的示例代码的文章就介绍到这了。
相关文章:
航拍无人机像素坐标转世界坐标
一、背景 已知相机参数(传感器宽度和高度、图像宽度和高度、焦距、相对航高、像主点坐标 ),在给定像素坐标的前提下,求世界坐标,大部分通过AI来实现,不知道哪个步骤有问题,望大家指正 二、代码…...
Linux系统学习——指令二
Linux系统学习——指令二 sed 指令perl 指令rpm 指令rz 和 sz 指令查看文件大小及压缩文件指令使用tar命令:使用zip命令:注意事项: 解压文件指令 sed 指令 使用sed命令:sed -i s/旧内容/新内容/g 文件名,这将会在文件…...
【逻辑回归】和【线性回归】的区别和联系-九五小庞
逻辑回归(Logistic Regression)和线性回归(Linear Regression)是两种常用的统计学习和机器学习技术,它们各自具有特定的应用场景和优势。以下是它们之间的主要区别和联系: 定义与目的 线性回归:…...
富格林:正视欺诈阻挠交易被骗
富格林指出,在交易的过程中,投资者们就算做了十分的把握,也难免会出现亏损。因此建议新手投资者,在准备投资时一定要做好充分的准备工作,明辨欺诈陷阱,同时学习正规的做单盈利技巧,这才能帮助我…...
如何在WPS中加载EndNote X9插件
如何在WPS中加载EndNote X9插件 步骤1:关闭WPS 确保所有WPS文档和窗口都已关闭。 步骤2:修改文件后缀 打开文件资源管理器,导航到路径:C:\Program Files (x86)\EndNote X9\Product-Support\CWYW。找到文件 Cwyw_X86.dat&#…...
vb.net小demo(计算器、文件处理等/C#也可看)
Demo1:使用窗体控件实现一个简易版计算器 Public Class Form1Private Sub Button_1_Click(sender As Object, e As EventArgs) Handles Button_1.ClickCalSubBox.Text Button_1.TextEnd SubPrivate Sub Button_2_Click(sender As Object, e As EventArgs) Handles …...
【vue3|第8期】深入理解Vue 3 computed计算属性
日期:2024年6月10日 作者:Commas 签名:(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释:如果您觉得有所帮助,帮忙点个赞,也可以关注我,我们一起成长;如果有不对的地方…...
《精通ChatGPT:从入门到大师的Prompt指南》附录C:专业术语表
附录C:专业术语表 本附录旨在为读者提供一本全面的术语表,帮助理解《精通ChatGPT:从入门到大师的Prompt指南》中涉及的各种专业术语。无论是初学者还是高级用户,这些术语的定义和解释将为您在使用ChatGPT时提供重要参考。 A AI&…...
YOLOv8可视化界面PYQT5
yolov8,可视化界面pyqt。支持图片检测,视频检测,摄像头检测等,实时显示检测画面。支持自定义数据集,计数,fps展示……,即插即用,无需更改太多代码...
远程代码执行和远程命令执行是一个东西吗
远程代码执行(Remote Code Execution,简称RCE)和远程命令执行在概念上有所区别,但两者都涉及到攻击者通过远程方式在目标系统上执行代码或命令。以下是两者的详细比较: 定义: 远程代码执行(RCE…...
C++ 20新特性之线程与jthread
💡 如果想阅读最新的文章,或者有技术问题需要交流和沟通,可搜索并关注微信公众号“希望睿智”。 为什么要引入jthread 在C 11中,已经引入了std::thread。std::thread为C标准库带来了一流的线程支持,极大地促进了多线程…...
赶紧收藏!2024 年最常见 20道并发编程面试题(七)
上一篇地址:赶紧收藏!2024 年最常见 20道并发编程面试题(六)-CSDN博客 十三、什么是线程局部存储(Thread-Local Storage)? 线程局部存储(Thread-Local Storage,简称TLS…...
HAL库开发--第一盏灯
知不足而奋进 望远山而前行 目录 文章目录 前言 学习目标 学习内容 需求 开发流程 项目创建 芯片配置 功能配置 时钟配置 项目配置 编写代码 编译测试 烧录失败解决 编辑 总结 前言 在嵌入式系统开发中,掌握HAL库开发流程、STMCubeMX配置过程以及…...
Linux C语言:变量的作用域和生命周期(auto、register、static和extern)
一、变量存储类型-auto 1、auto变量的说明 变量在程序中使用时,必须预先说明它们的存储类型和数据类型。 变量说明的一般形式是: <存储类型> <数据类型 > <变量名> ; <存储类型>是关键词auto、register、static和extern<…...
AI Stable diffusion 报错:稳定扩散模型加载失败,退出
可能是内存不够,看看你最近是加了新的大的模型,可以把你的stable-diffusion-webui\models\Stable-diffusion目录下的某个ckpt删除掉,可能ckpt太大,无法加载成功; Stable diffusion model failed to load, exiting 如图…...
[Python学习篇] Python循环语句
while 循环 语法: while 条件: 条件成立后会重复执行的代码 ...... 示例1:死循环 # 这是一个死循环示例 while True:print("我正在重复执行")示例2:循环指定次数 i 1 while i < 5:print(f"执行次数 {i}")…...
MongoDB 正则表达式
MongoDB 正则表达式 MongoDB 是一个流行的 NoSQL 数据库,它提供了强大的查询功能,包括对正则表达式的支持。正则表达式是一种强大的文本搜索工具,它允许用户根据特定的模式匹配和搜索字符串。在 MongoDB 中,正则表达式可以用于查…...
Django配置连接池:使用django-db-connection-pool配置连接池
一、该三方库文档使用 github地址: https://github.com/altairbow/django-db-connection-pool/blob/1.2.5/README_CN.mdhttps://github.com/altairbow/django-db-connection-pool/blob/1.2.5/README_CN.md1、选择指定版本,查看指定版本的文档和配置&am…...
SpringBoot整合钉钉实现消息推送
前言 钉钉作为一款企业级通讯工具,具有广泛的应用场景,包括但不限于团队协作、任务提醒、工作汇报等。 通过Spring Boot应用程序整合钉钉实现消息推送,我们可以实现以下功能: 实时向指定用户或群组发送消息通知。自定义消息内容…...
【机器学习】集成学习方法:Bagging与Boosting的应用与优势
🔥 个人主页:空白诗 文章目录 引言一、集成学习的定义二、Bagging方法1. 随机森林(Random Forest)2. 其他Bagging方法 二、Boosting方法1. 梯度提升树(Gradient Boosting Machine, GBM)解释GBM的基本原理和…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
