【单目测距】单目相机测距(三)
文章目录
- 一、前言
- 二、测距代码
- 2.1、地面有坡度
- 2.2、python代码
- 2.2.1、旋转矩阵转角度
- 2.2.2、角度转旋转矩阵
- 2.2.3、三维旋转原理 (Rotation 原理)
- 2.2.4、完整代码
- 2.3、c++ 代码
一、前言
- 上篇博客【单目测距】单目相机测距(二) 有讲到当相机不是理想状态,实际情况如相机安装时候有角度偏差,需要对相机进行标定。同时也分析影响测距误差的多个因素以及各个因素影响权重。
- 上述都是基于地面与自身平行,当地面存在坡度尤其是上下坡度的时候。此时测距误差会非常之大。如果有 1° 坡度,那么目标在 10 m 处测距就有 20 cm 误差。
- 如果我们提前已知到地面的坡度 sigma ,我们就应该实时去修正相机外参,此片博客提供传入地面角度,实时修正相机外参的思路与代码。
二、测距代码
- 先回顾一下往期测距代码【单目测距】单目相机测距(二)
- 输入相机内参、外参、相机高度是提前标定完成
- 目标像素点由目标检测 bbox 求出。
import numpy as nph = 1.5 # 相机离地面1.5m高
pitch = -0.023797440420123328 # 弧度
pixe_x, pixe_y = 888, 700 # 图像像素点,接地点
CameraMat = np.array([[1008, 0, 945],[0, 1009, 537],[0, 0, 1]]) # 相机内参R = np.array([[-0.0330564609, 0.0238237337, 0.999169505],[0.999452124, -0.000862625046, 0.0330863791, ],[0.00165014972, 0.999715802, -0.0237821659]]) # 旋转矩阵
T = np.array([0, 0, -1.5])sigma = np.arctan((pixe_y - CameraMat[1][2]) / CameraMat[1][1])
z = h * np.cos(sigma) / np.sin(sigma + pitch) # 深度
x_pixe, y_pixe = 2 * CameraMat[0][2] - pixe_x, 2 * CameraMat[1][2] - pixe_y # 根据自定坐标系选择是否中心对称转换
camera_x = z * (x_pixe / CameraMat[0][0] - CameraMat[0][2] / CameraMat[0][0])
camera_y = z * (y_pixe / CameraMat[1][1] - CameraMat[1][2] / CameraMat[1][1])
camera_z = z
distance_machine_direction = R[0][0] * camera_x + R[0][1] * camera_y + R[0][2] * camera_z + T[0] # 纵向距离
distance_transverse_direction = R[1][0] * camera_x + R[1][1] * camera_y + R[1][2] * camera_z + T[1] # 横向距离
print(distance_machine_direction, distance_transverse_direction)
2.1、地面有坡度
- 根据前面分析,如果地面有坡度,我们应该实时去修正相机外参。具体怎么做,也很简单。就是实时去更新我们的 pitch 角与相机的外参。
- 我们前提是需要知道地面坡度是多少,关于如何获取地面坡度,以后有机会再谈。
2.2、python代码
python 从旋转矩阵转化到角度、从角度到转化矩阵,主要用到 scipy 库中的 Rotation。
2.2.1、旋转矩阵转角度
import numpy as np
from scipy.spatial.transform import Rotationr = np.array([-0.0517, -0.0611, 0.9968, 0.9987, 0.0011, 0.0519, -0.0042, 0.9981, 0.0609]).reshape(3, 3)
euler_r = Rotation.from_matrix(r).as_euler('zxy', degrees=False) # zxy 是 外旋顺序。degrees False 显示弧度,True 显示角度
print(euler_r)# [ 1.56967277 -0.0518037 1.50976086]
2.2.2、角度转旋转矩阵
from scipy.spatial.transform import Rotationeuler_r = [1.56967277, -0.0518037, 1.50976086]
new_r = Rotation.from_euler("zxy", [euler_r[0], euler_r[1], euler_r[2]], degrees=False).as_matrix()
2.2.3、三维旋转原理 (Rotation 原理)
import numpy as np
from scipy.spatial.transform import Rotationdef get_r_matrix(str, alpha):sin = -np.sin(alpha)cos = np.cos(alpha)res = np.eye(3)if str == "z":res = np.array([[cos, sin, 0],[-sin, cos, 0],[0, 0, 1]])elif str == "y":res = np.array([[cos, 0, -sin],[0, 1, 0],[sin, 0, cos]])elif str == "x":res = np.array([[1, 0, 0],[0, cos, sin],[0, -sin, cos]])return reseuler_r = [1.56967277, -0.0518037, 1.50976086]
a, b, c = euler_r[0], euler_r[1], euler_r[2]z = get_r_matrix("z", a)
x = get_r_matrix("x", b)
y = get_r_matrix("y", c)
mtx = y @ x @ z
mtx_1 = Rotation.from_euler("zxy", [a, b, c], degrees=False).as_matrix()
print(mtx, mtx_1) # 结果完全一致
2.2.4、完整代码
综上所述,可得
import numpy as np
from scipy.spatial.transform import Rotationdiff_pitch = -0.01 # 假设当前地面坡度为 -0.01 弧度
h = 1.5 # 相机离地面1.5m高
pitch = -0.023797440420123328 # 弧度
pitch = pitch + diff_pitch
pixe_x, pixe_y = 888, 700 # 图像像素点,接地点
CameraMat = np.array([[1008, 0, 945],[0, 1009, 537],[0, 0, 1]]) # 相机内参original_r = np.array([[-0.0330564609, 0.0238237337, 0.999169505],[0.999452124, -0.000862625046, 0.0330863791],[0.00165014972, 0.999715802, -0.0237821659]]) # 旋转矩阵
euler_r = Rotation.from_matrix(original_r).as_euler('zxy', degrees=False)
R = Rotation.from_euler("zxy", [euler_r[0], euler_r[1], euler_r[2] + diff_pitch], degrees=False).as_matrix()T = np.array([0, 0, -1.5]) # 平移矩阵sigma = np.arctan((pixe_y - CameraMat[1][2]) / CameraMat[1][1])
z = h * np.cos(sigma) / np.sin(sigma + pitch) # 深度
x_pixe, y_pixe = 2 * CameraMat[0][2] - pixe_x, 2 * CameraMat[1][2] - pixe_y # 根据自定坐标系选择是否中心对称转换
camera_x = z * (x_pixe / CameraMat[0][0] - CameraMat[0][2] / CameraMat[0][0])
camera_y = z * (y_pixe / CameraMat[1][1] - CameraMat[1][2] / CameraMat[1][1])
camera_z = z
distance_machine_direction = R[0][0] * camera_x + R[0][1] * camera_y + R[0][2] * camera_z + T[0] # 纵向距离
distance_transverse_direction = R[1][0] * camera_x + R[1][1] * camera_y + R[1][2] * camera_z + T[1] # 横向距离
print(distance_machine_direction, distance_transverse_direction)
2.3、c++ 代码
知道了 2.2.3 中的三维旋转原理,那我们利用矩阵乘法就可以轻松获得新外参啦
double pitchDiff = -0.01;cv::Mat initR = (cv::Mat_<double>(3,3) << -0.0330564609, 0.0238237337, 0.999169505,0.999452124, -0.000862625046, 0.0330863791, 0.00165014972, 0.999715802, -0.0237821659); // 相机初始外参cv::Mat pitchR = (cv::Mat_<double>(3, 3) << cos(pitchDiff), 0, sin(pitchDiff), 0, 1, 0, -sin(pitchDiff), 0, cos(pitchDiff));cv::Mat curR = pitchR * initR;
相关文章:
【单目测距】单目相机测距(三)
文章目录 一、前言二、测距代码2.1、地面有坡度2.2、python代码2.2.1、旋转矩阵转角度2.2.2、角度转旋转矩阵2.2.3、三维旋转原理 (Rotation 原理)2.2.4、完整代码 2.3、c 代码 一、前言 上篇博客【单目测距】单目相机测距(二) 有讲到当相机不是理想状态…...
Evaluating Large Language Models: A Comprehensive Survey
本文是LLM系列文章,针对《Evaluating Large Language Models: A Comprehensive Survey》的翻译。 评估大型语言模型:一项综合调查 摘要1 引言2 分类和路线图3 知识和能力评估4 对齐评估5 安全评估6 专业LLM评估7 评估组织8 未来方向9 结论 摘要 大型语…...
ElasticSearch 实现 全文检索 支持(PDF、TXT、Word、HTML等文件)通过 ingest-attachment 插件实现 文档的检索
一、Attachment 介绍 Attachment 插件是 Elasticsearch 中的一种插件,允许将各种二进制文件(如PDF、Word文档等)以及它们的内容索引到 Elasticsearch 中。插件使用 Apache Tika 库来解析和提取二进制文件的内容。通过使用 Attachment 插件&a…...
【Head First 设计模式】-- 策略模式
一、背景 Head First 设计模式第一章设计模式入门–策略模式 二、工具箱的工具(本章) 1、OO基础 封装 继承 多态 抽象 2、OO原则 封装变化 面向接口编程,而非面向实现编程 组合优于继承 3、OO模式 策略模式,所谓策略模式就是定义…...
能链智电,“重”症在身
文 | 智能相对论 作者 | 陈选滨 在过去的1-9月,充电基础设施增量为243.2万台,新能源汽车销量627.8万辆,充电桩与新能源汽车的增量比为1:2.6,距离工信部此前提出“2025年实现车桩比2:1,2030年实现车桩比1:…...
python 视频硬字幕去除 内嵌字幕去除工具 vsr
项目简介 开源地址:https://github.com/YaoFANGUK/video-subtitle-remover Video-subtitle-remover (VSR) 是一款基于AI技术,将视频中的硬字幕去除的软件。 主要实现了以下功能: 无损分辨率将视频中的硬字幕去除,生成去除字幕后…...
蓝桥等考C++组别六级004
第一部分:选择题 1、C L6 (15分) 关于switch语句,以下说法正确的是( )。 A. break语句只能用于switch语句。 B. switch语句中可以使用多个default语句。 C. switch语句中只能使用一个break语句。 D. …...
SpringBoot之Swagger
文章目录 前言一、Swagger简介二、SpringBoot集成Swagger三、配置Swagger四、配置扫描接口五、配置Swagger开关六、配置API分组七、实体配置八、常用注解 前言 作为后端开放人员,最烦的事就是自己写接口文档和别人没有写接口文档,不管是前端还是后端开发…...
抖音小店新的流量变现新时代!
随着短视频平台的日益崛起,抖音小店已成为电商领域的一股不可忽视的力量。抖音小店不仅具有极高的流量优势,还为众多商家提供了一个全新的销售渠道。那么,如何才能充分利用抖音小店的优势,打造出爆款商品,实现流量变现…...
软件架构师
软件架构师在软件开发过程中扮演着至关重要的角色,其主要职责包括: 需求分析:与用户和开发团队沟通,确定软件的需求和功能。设计架构:根据需求分析,设计软件的架构,包括系统架构、数据库架构、…...
postman接口测试
postman使用 开发中经常用postman来测试接口,一个简单的注册接口用postman测试: 接口正常工作只是最基本的要求,经常要评估接口性能,进行压力测试。 postman进行简单压力测试 下面是压测数据源,支持json和csv两个格式…...
技术分享 | web自动化测试-PageObject 设计模式
为 UI 页面写测试用例时(比如 web 页面,移动端页面),测试用例会存在大量元素和操作细节。当 UI 变化时,测试用例也要跟着变化, PageObject 很好的解决了这个问题。 使用 UI 自动化测试工具时(包…...
Mall4cloud 微服务商城系统 2.0 发布
导读现在 jdk17 和 spring boot 以及 spring cloud alibaba 2022 的第三方依赖已经趋于成熟,所以 mall4cloud 也一把梭哈做了升级嗷。 本次更新重点: 系统由 jdk8 最低要求升级到 jdk17spring boot 由 2.7.x 升级到 3.1.xjavax 升级到 jakartaspring-cl…...
SpringBoot进制转换规则问题
1.填写yml文件 dataSource:driver-class-name: com.mysql.jdbc.Driver789password: 01272.测试类 package com.forever;import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.Spri…...
12.输入一个小于1000的整数,输出平方根(不是整数,输出整数部分)
#include<stdio.h> #include<math.h>int fun(int n){int b;b pow(n,0.5);printf("%d",b);}int main(){int n;scanf("%d",&n); fun(n);return 0;}...
Django框架的推导
文章目录 Web应用简介什么是Web框架?什么是Web?应用程序的两种模式Web应用程序的优缺点 手写Web框架HTTP协议的相关知识1.四大特性2.请求数据格式3.响应数据格式 手写框架 使用wsgiref模块基于wsgiref模块搭建Web框架(最初版)基于wsgiref模块搭建Web框架…...
广东开放大学:电大搜题助力学子迎考利器
近年来,广东开放大学一直致力于为广大学子提供优质的教育资源和学习服务。作为一所专注于远程教育的学府,广东开放大学不仅拥有雄厚的师资力量和丰富的教育经验,还致力于创新教学手段,为学生提供更便捷、高效的学习体验。在这个信…...
linux 7za 编译安装
本文主要介绍了在linux下安装7z命令的方法,同时介绍了7z命令的使用。7z压缩格式拥有众多优点,具有极高的压缩比率 wget https://zenlayer.dl.sourceforge.net/project/p7zip/p7zip/16.02/p7zip_16.02_src_all.tar.bz2 tar -xjvf p7zip_16.02_src_all.ta…...
【Edge】微软Edge每次启动自动导入Chrome收藏夹,无法取消“每次启动浏览器时导入浏览数据”功能的解决方法(202311)
写在前面 Edge现在也不管用户体验了吗? 这个BUG都快一个月了,还没见修复,从118.0.2088开始,我是在2023年10月份一次更新后发现的这个BUG,结果社区论坛什么信息都没有,英文也没收到。 Edge的BUG现象 不知道哪次Edge…...
报错RuntimeError: no valid convolution algorithms available in CuDNN
报错信息如下RuntimeError: no valid convolution algorithms available in CuDNN 出现这个问题既不是cuda与cudnn版本不匹配,也不是英伟达显卡驱动需要更新!而是因为你的显存过低不能训练,解决办法是使用混精度训练!!…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...
解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...
[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...
【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...
