基于yolov5的单目测距实现与总结+相机模型+标定

写这篇文章的目的是为了总结我之前看的标定,相机模型以及单目测距的内容,如果有错误,还请不吝赐教。
参考链接:
相机模型、相机标定及基于yolov5的单目测距实现
深度学习目标检测目标追踪单目测距
单目测距+代码部署(目标检测+车辆/行人等测距)
单镜头视觉系统检测车辆的测距方法
相机模型与视觉测距不完全指南
单目测距(yolo目标检测+标定+测距代码)
【markdown】 数学公式
老规矩先上参考链接!感谢大佬们的无私奉献!!

代码链接
对代码的部分说明:
1.能跑通最新版本的yolov5就肯定能跑通我的这份代码,就是参考最新代码修改的。
2.权重和数据我就直接放仓库里了,clone下来直接跑,在inference/output里看结果。
3.觉得有用欢迎fork and star!

文章目录

  • 1 前言
  • 2 相机模型及单目测距原理
    • 2.1 单目测距能精确测距么?
    • 2.2 测距非常重要的几个公式和原理
      • 2.2.1 相机成像模型
      • 2.2.1 坐标系转换
  • 3 相机内参和外参的标定
  • 4 基于yolov5的单目测距实现及关键代码
      • 4.1 单目测距模型
      • 4.2 目标点的选取
      • 4.3 距离的求取

1 前言

在摄像头成像过程中,物体反射的光线通过摄像头的凸透镜打在成像器件上,形成一张图片。这是一个三维物体转换为二维图像的过程。在这个过程中,丢失了物体的深度信息,所以单目摄像头很难测距。但是,我们可以通过一个强假设,来简单计算物体的距离,即假设物体是处于地面上。具体意思下面再详细说。

2 相机模型及单目测距原理

相机模型可以简单看成一个凸透镜成像的模型。下图中,XcYcZc是相机坐标系,其原点为光心O,是相机凸透镜的中心点。x-o1-y坐标系是图像坐标系。
图片从b站up主(uid:109364003)的视频中截图的
图片从b站up主(uid:109364003)的视频中截图的
图中有一个车辆,且车辆在地面上,其接地点Q必定在地面上。那么Q点的深度便可以求解出来。具体求解步骤懒得打公式了,就截图了。在单目测距过程中,实际物体上的Q点在成像的图片上对应Q’点,Q’点距离o1点沿y轴的距离为o1p’。这个距离o1p’除以y轴像素焦距fy (单位为pixel) ,再求arctan即可得到角度b’。然后按图中步骤很容易理解了。
在这里插入图片描述
在按图中步骤求解深度OD时,如果相机高度H、相机光轴与水平线的夹角a没有准确测量的话,会对测距精准度造成较大影响。所以用于自动驾驶时,随着车身抖动,测距精度会很低。如果路面不是水平的,而是具有曲率的,那该方法也将失效。

这部分我还是想加点内容进来。解答了我的疑惑。

2.1 单目测距能精确测距么?

那么有一个问题,在已知所有相机参数K, R, T 的情况下,能否通过图像坐标 p 反推出对应的世界坐标 P 呢?
在这里插入图片描述
这里我们从几何关系上看:只要世界中的点 P 在 o c P 1 → \overrightarrow{o_{c}P_{1}} ocP1 射线上,那么最终都会通过相机投影到图像中 p 的点,所以单摄像头无法精确测距。相机模型本质是一种从世界坐标系3D → \rightarrow 像素坐标系2D的投影变换,在投影变换中丢失了深度信息。
大佬这段写的特别好!
在这里插入图片描述

2.2 测距非常重要的几个公式和原理

原理部分

2.2.1 相机成像模型

想要得到距离信息需要获得三维真实世界里的点,而由于处理的对像是摄像 头捕捉后的二维平面图像,因此如何将二维图像上的某个点转换为三维世界里的 点是值得考虑的问题。进一步的,把图像上的点转换到真实世界的点,就需要进行 像素坐标系、图像坐标系、相机坐标系以及世界坐标系 之间的相互转换。四种 坐标系之间的相互关系如图所示。坐标系描述如下:
在这里插入图片描述

(1)像素坐标系。数字图像一般是三维图像并且由众多像素点组合而成的,像 素坐标系的原点为 O2,以宽度方向为 u 轴,以高度方向为 v 轴。
(2)图像坐标系。图像坐标原点为 O1,并且像素坐标系和图像坐标系是平行的, 以图像宽度方向为 x 轴,以高度方向为 y 轴,长度单位为 mm。
(3)相机坐标系。相机坐标系原点 Oc,Xc轴、Yc 轴分别是与图像坐标系下的 x 轴、y 轴相互平行,相机 Zc轴和摄像头光轴重合。
(4)世界坐标系。我们所处的环境即是在世界坐标系之下,也就是图中 Xw-Yw-Zw 平面。Pw 通过真实世界上的一点至图像上的 P 点,完成从世界坐标到 图像上坐标的转换。

我看了很多遍原理,这部分是真正让我醍醐灌顶的。

2.2.1 坐标系转换

(1)像素坐标系转换到图像坐标系 像素坐标系是以像素来表示各个像素位置信息的,但是它不能够表达出图像 中物体的物理大小,因此需要进行坐标系之间的转换。略
(2)图像坐标系变换到相机坐标系 略
(3)相机坐标系变换到世界坐标系
在这里插入图片描述
相机坐标系变换到世界坐标系可以描述为一个旋转平移的过程,分别将旋转 和平移的分量加起来就是整个坐标系转换的全过程了。对于旋转过程,假设相机 坐标系的 Z
在这里插入图片描述
同理,绕 X 轴旋转会得到如下关系
在这里插入图片描述
绕 Y 轴旋转会得到如下关系:
在这里插入图片描述
对于平移分量来说,可以表达为:
在这里插入图片描述
这部分公式很赞!

3 相机内参和外参的标定

这部分优秀文献特别多,等我闲的时候再来加。

4 基于yolov5的单目测距实现及关键代码

estimate_distance.py为主程序。该程序中有一个DistanceEstimation类,该类的主要成员函数有camera_parameters(), object_point_world_position(), distance(), Detect(). 在Detect函数中调用yolov5检测得到目标框后,便可以提取目标框的底边的中点作为2中所述的测距所需的Q’点。然后按照2中所述原理,便可以求得到Q点的Xw和Yw坐标。取Xw和Yw的坐标的平方和,再开根号便得到了目标的直线距离。

4.1 单目测距模型

在完成了相机畸变矫正和相机内外参数的求取之后,建立了如下的单目测距 模型,再结合第四章目标检测获取的矩形框就可以进行距离的求取。
在这里插入图片描述
测距模型可以看作是一个凸透镜成像的过程。上图中,Xc-Yc-Zc是相机坐标系, xO1y是图像坐标系,O1O为焦距f,x1O2y1是地面坐标系,OO2为摄像头安装高度h。 图中有一辆车在地面上,那么其接地点Q必定在地面上。在单目测距过程中,实际 物体上的Q点在成像的图片上对应Q'点,Q'点在y轴上的投影为P'点。水平线 与Zc轴的夹角为α,Zc光轴与PP'的夹角为β,直线OP与地面x1轴的夹角为γ。

4.2 目标点的选取

根据目标检测框,并且已知相机内外参数, 将其联合起来就可以得到测距值。具体的本文首先要选取参考点(目标点),拟选取目标框底部中点位置作为参考点,并根据大量目标框的获取结果。观察到目标矩形框比目标物实际尺寸略大,因此采取偏移的方式对目标参考点进行矫正以保证 测距精确度。本文采取让参考点向上偏移d个像素点,并且获取的是目标框的左上角和右下角坐标,因此参考点坐标可以表示为:
在这里插入图片描述
在这里插入图片描述
然而上述目标点适合前方物体在本车正前方的场景,当面对上图场景时, 目标物会出现在本车侧方位置。如果再把目标框下部中点作为测距目标点,会出 现目标点严重偏离车辆正下方的问题,存在目标点出现在汽车中心位置左侧或中 心右侧的现象,这会造成测距精度不高的缺点。因此,进一步的对其进行改进, 当目标点(xp,yp)与图像下部中点斜率k满足阈值δ时,就会更新xp'的值,新的xp' 可以表示为:
在这里插入图片描述
其中λ为偏移权重系数,当k值为负时,λ为负;当k值为正时,λ也为正。
在这里插入图片描述

4.3 距离的求取

由上面求得的内参矩阵可得fx,fy。由测距模型可以推得Zc 光轴与PP'的夹角β:
在这里插入图片描述
直线OP与地面x1轴的夹角γ可以看作是水平线与PP'的夹角 Z c {Z_{c}} Zc 深度公式可以表示为:
在这里插入图片描述
把图像坐标点(xp,yp)转换为相机坐标系上的点可以表示为:
在这里插入图片描述
在这里插入图片描述
得到最后的距离公式为:
在这里插入图片描述
核心代码:

	cam_H = 1 # 相机离地的高度angle_a = 0 # 相机光轴与水平线的夹角aangle_b = math.atan((v1 - self.H / 2) / fy)angle_c = angle_b + angle_aprint('angle_b', angle_b)depth = (cam_H / np.sin(angle_c)) * math.cos(angle_b)#目标深度print('depth', depth)k_inv = np.linalg.inv(in_mat)#K^-1 内参矩阵的逆p_inv = np.linalg.inv(out_mat)#R^-1 外参矩阵的逆print("out---:",p_inv)point_c = np.array([x_d, y_d, 1])  ##图像坐标point_c = np.transpose(point_c)#目标的世界坐标print('point_c', point_c)print('in----', k_inv)##相机坐标系和图像坐标系下物体坐标可按照下式转换。c_position = np.matmul(k_inv, depth * point_c)#Zc*[u,v,1].T*ins^-1==[Xc,Yc,Zc].T #坐标转换

别人的实验结果和分析:
为了验证方法的合理性,本文将实测距离与仿真结果进行对比验证。因为目 标物的距离不同会造成预测的精度也不同,具体实验流程如下:
(1) 用棋盘网格图对车载摄像头进行标定,将棋盘格图放在摄像头前的不同距 离以及倾斜不同的角度,将采集到的17张图像导入到软件中来求解相机内外参数 以及畸变系数。

(2)采集不同距离下的车、行人等图像,并将出现在图像中的目标物利用卷尺 对其真实距离进行测量。

(3)利用矫正公式将采集到的图像进行矫正,以获得良好的测试位置。

(4)将矫正后的图像数据集输入到目标检测模型和测距模型中进行仿真测距。

这部分 阿利同学 这位作者说自己的结果跟prescan仿真软件相比,结果误差5%。作者认为是可以用的,我并没有去验证这部分的精确性。但我认为作者原理部分写的很好。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/762700.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Flask开发实战】防火墙配置文件解析(二)之shell读取内容

一、前言 上一篇文章中,介绍了防火墙配置文件包含的基本元素和格式样式,并模拟了几组有代表性的规则内容,作为基础测试数据。在拿到基础测试数据后,关于我们最终想解析成的数据是什么样式的,其实不难看出,…

Dynamo设置明细表字段格式——保留小数位数

Hello大家好!我是九哥~ 今天简单分享一个API的用法,就是设置明细表的中字段的字段格式。 本次呢,主要介绍下如何通过Dynamo设置长度、面积等几种字段的格式,设置小数位数的显示,如下图: 当然了&#xf…

基于ssm的网络游戏公司官方平台设计与实现论文

摘 要 互联网发展至今,无论是其理论还是技术都已经成熟,而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播,搭配信息管理工具可以很好地为人们提供服务。针对网络游戏信息管理混乱,出错率高,信息安全性差…

函数递归的总结回顾

函数递归的本质就是其名字——递与归。先递出去, 再收回来。 而递归的思想就是为了让一个复杂的问题变成一个简单的问题 按照我目前的理解,函数递归有两点很重要。一个是它的限定条件,另一个就是函数体内“自调”(就是自我调用语句…

1-Flume中agent的source

Flume(1.11.0版本) 简介 概述 Flume本身是由Cloudera公司开发的后来贡献给了Apache的一套针对日志数据进行收集(collecting)、汇聚(aggregating)和传输(moving)的机制 Flume本身提供了简单且灵活的结构来完成日志数据的传输 Flume有两大版本&#x…

jQuery 选择器--获取元素

文章目录 1 jQuery 基础选择器2 层级选择器3 隐式迭代(重要)4 jQuery 筛选选择器5 jQuery 筛选方法(重点)案例--下拉菜单 6 jQuery 排他思想*案例--左右Tab栏切换 7 jQuery 链式编程 1 jQuery 基础选择器 2 层级选择器 3 隐式迭代(重要) 示例: 4 jQuery 筛选选择器…

流畅的 Python 第二版(GPT 重译)(十二)

第五部分:元编程 第二十二章:动态属性和属性 属性的关键重要性在于,它们的存在使得将公共数据属性作为类的公共接口的一部分完全安全且确实可取。 Martelli、Ravenscroft 和 Holden,“为什么属性很重要” 在 Python 中&#xff0…

前端如何一次处理十万条数据的渲染

前端如何一次处理十万条数据的渲染 一、下载第三方插件二、在入口文件引入三、示例 一、下载第三方插件 npm install --save el-table-infinite-scroll二、在入口文件引入 import ElTableInfiniteScroll from "el-table-infinite-scroll"; Vue.use(ElTableInfinite…

docker 配置国内阿里镜像源

在/etc/docker/目录下新建daemon.json文件 在文件中写入 {"registry-mirrors": ["https://jmphwhtw.mirror.aliyuncs.com"] } 以管理员身份运行命令 systemctl daemon-reload systemctl restart docker

项目中如何进行限流(限流的算法、实现方法详解)

❤ 作者主页:李奕赫揍小邰的博客 ❀ 个人介绍:大家好,我是李奕赫!( ̄▽ ̄)~* 🍊 记得点赞、收藏、评论⭐️⭐️⭐️ 📣 认真学习!!!🎉🎉 文章目录 限流的算法漏…

MFO-CNN-LSTM多输入分类预测|飞蛾扑火算法优化的卷积-长短期神经网络|Matlab

目录 一、程序及算法内容介绍: 基本内容: 亮点与优势: 二、实际运行效果: 三、算法介绍: 四、完整程序下载: 一、程序及算法内容介绍: 基本内容: 本代码基于Matlab平台编译&am…

最新优质电商API接口,附带Python教程

接口信息 API 接口是应用程序编程接口(Application Programming Interface)的缩写。 它是一组定义了软件组件之间如何交互和通信的规则和规范。简单来说,API 接口就是让不同的软件系统能够相互“交流”和“合作”的桥梁。打个比方&#xff…

onlyoffice第一次打开特别慢的问题优化

分析问题 上传oss 找到fonts上传到oss中 更改nginx配置 找到nginx所在位置 找到ds-docservice.conf #### onlyoffice二次开发,优化fonts请求速度的问题 location ~* /8.0.0-99/fonts(.*){return https://xxxx-xxxx.cos.ap-shanghai.myqcloud.com/fonts$1?…

jQuery 基础

文章目录 1. jQuery 概述1.1 JavaScript 库1.2 jQuery 概念1.3 jQuery 优点 2. jQuery 基本使用2.1 下载2.2 使用步骤2.3 jQuery 的入口函数2.4 jQuery 的顶级对象 $2.5 DOM 对象和 jQuery 对象DOM 对象和 jQuery 对象相互转换方法 1. jQuery 概述 1.1 JavaScript 库 1.2 jQue…

一篇文章带你了解知乎热门话题的撰写技巧

在当今信息高速发展的时代,人们越来越依赖网络获取知识。而知乎作为一个知识分享和知识传播的平台,吸引了大量用户的关注和参与。那么,如何在知乎上撰写一篇引人注目的文章呢?接下来,腾轩科技传媒探讨一下知乎文章的撰…

活动回顾 | 走进华为向深问路,交流数智办公新体验

3月20日下午,“企业数智办公之走进华为”交流活动在华为上海研究所成功举办。此次活动由上海恒驰信息系统有限公司主办,华为云计算技术有限公司和上海利唐信息科技有限公司协办,旨在通过对企业数字差旅和HR数智化解决方案的交流,探…

MySQL之基本操作与用户授权

一 基本操作 1 SQL分类 数据库:database 表:table,行:row 列:column 索引:index 视图:view 存储过程:procedure 存储函数:function 触发器:trigger 事…

【强化学习公式推导】状态价值函数与动作价值函数贝尔曼期望方程,贝尔曼最优方程推导过程

【强化学习公式推导】状态价值函数与动作价值函数贝尔曼期望方程,贝尔曼最优方程推导过程 1.回报 2.当前时刻的回报与下一时刻回报的关系 3.状态价值函数 4.动作价值函数 5.状态价值函数与动作状态价值函数的关系 6.贝尔曼期望方程 7.状态价值函数的贝尔…

迷宫(蓝桥杯)——DFS和BFS

迷宫 题目描述 下图给出了一个迷宫的平面图,其中标记为 1 的为障碍,标记为 0 的为可以通行的地方。 010000 000100 001001 110000迷宫的入口为左上角,出口为右下角,在迷宫中,只能从一个位置走到这 个它的上、下、左…

[云] vmware: host: net: Net.CoaleseDefaultOn

https://communities.vmware.com/t5/Storage-Performance/Advanced-Networking-Performance-Options/ta-p/2792649 在vsphere client下的路径是: 选择使用的host -> 右键setting->configure-> system->advanced system setting->edit->Net.Coales…