双目视觉搭配YOLO实现3D测量

一、简介 

双目(Stereo Vision)技术是一种利用两个相机来模拟人眼视觉的技术。通过对两个相机获取到的图像进行分析和匹配,可以计算出物体的深度信息。双目技术可以实现物体的三维重建、距离测量、运动分析等应用。

双目技术的原理是通过两个相机之间的基线距离来计算出物体的深度。当两个相机捕捉到的图像中存在物体时,它们会分别捕捉到该物体的两个视角。通过计算两个视角之间的差异,可以得到物体的深度信息。

YOLO(You Only Look Once)是一种目标检测算法。与传统的目标检测算法不同,YOLO算法可以在一次前向传递中完成对图像中所有目标的检测和定位。YOLO算法的特点是速度快,可以实时处理视频流,适用于实时场景下的目标检测任务。

YOLO算法采用了将输入图像分割为网格的方式,并在每个网格上预测目标的位置和类别。通过使用卷积神经网络,YOLO算法可以提取出图像中的特征,并将其应用于目标检测任务。相较于其他目标检测算法,YOLO算法具有更高的处理速度和较低的定位误差。

由于3D目标检测的数据集制作困难,本人采用双目+单目目标检测的方式   将识别和3D检测进行分开计算,成功实现3D目标检测和体积测量

3D测量

 

可以看出来精度还是相当高的,但是周围不能有杂物的影响

有需要合作的请私聊博主

二、双目原理

双目标定 > 立体校正(含消除畸变) > 立体匹配 > 视差计算 > 深度计算(3D坐标)计算

2.1 立体校正


2.1.1 校正目的
立体校正利用双目标定的内外参数(焦距、成像原点、畸变系数)和双目相对位置关系(旋转矩阵和平移向量),分别对左右视图进行消除畸变和行对准,使得左右视图的成像原点坐标一致、两摄像头光轴平行、左右成像平面共面、对极线行对齐。

校正前的左右相机的光心并不是平行的,两个光心的连线就叫基线,像平面与基线的交点就是极点,像点与极点所在的直线就是极线,左右极线与基线构成的平面就是空间点对应的极平面。
校正后,极点在无穷远处,两个相机的光轴平行。像点在左右图像上的高度一致。这也就是极线校正的目标。校正后做后续的立体匹配时,只需在同一行上搜索左右像平面的匹配点即可,能使效率大大提高。

2.1.2 校正方法
实验利用OpenCV中的stereoRectify()函数实现立体校正,stereoRectify()函数内部采用的是Bouguet的极线校正算法,Bouguet算法步骤:
1、将右图像平面相对于左图像平面的旋转矩阵分解成两个矩阵Rl和Rr,叫做左右相机的合成旋转矩阵
2、将左右相机各旋转一半,使得左右相机的光轴平行。此时左右相机的成像面达到平行,但是基线与成像平面不平行
3、构造变换矩阵Rrect使得基线与成像平面平行。构造的方法是通过右相机相对于左相机的偏移矩阵T完成的
4、通过合成旋转矩阵与变换矩阵相乘获得左右相机的整体旋转矩阵。左右相机坐标系乘以各自的整体旋转矩阵就可使得左右相机的主光轴平行,且像平面与基线平行
5、通过上述的两个整体旋转矩阵,就能够得到理想的平行配置的双目立体系图像。校正后根据需要对图像进行裁剪,需重新选择一个图像中心,和图像边缘从而让左、右叠加部分最大
校正后的效果图:

 2.1.2 相关代码

def getRectifyTransform(height, width, config):# 读取内参和外参left_K = config.cam_matrix_leftright_K = config.cam_matrix_rightleft_distortion = config.distortion_lright_distortion = config.distortion_rR = config.RT = config.T# 计算校正变换R1, R2, P1, P2, Q, roi1, roi2 = cv2.stereoRectify(left_K, left_distortion, right_K, right_distortion,(width, height), R, T, alpha=0)map1x, map1y = cv2.initUndistortRectifyMap(left_K, left_distortion, R1, P1, (width, height), cv2.CV_32FC1)map2x, map2y = cv2.initUndistortRectifyMap(right_K, right_distortion, R2, P2, (width, height), cv2.CV_32FC1)return map1x, map1y, map2x, map2y, Q# 畸变校正和立体校正
def rectifyImage(image1, image2, map1x, map1y, map2x, map2y):rectifyed_img1 = cv2.remap(image1, map1x, map1y, cv2.INTER_AREA)rectifyed_img2 = cv2.remap(image2, map2x, map2y, cv2.INTER_AREA)return rectifyed_img1, rectifyed_img2

立体匹配和视差计算
立体匹配也称作视差估计,立体匹配可划分为四个步骤:匹配代价计算、代价聚合、视差计算和视差优化。立体校正后的左右两幅图像得到后,匹配点是在同一行上的,可以使用OpenCV中的BM算法或者SGBM算法计算视差图。由于SGBM算法的表现要远远优于BM算法,因此采用SGBM算法获取视差图。在立体匹配生成视差图后,可以对视差图进行后处理,如滤波,空洞填充等方法,从而改善视差图的视觉效果

相关代码

def stereoMatchSGBM(left_image, right_image, down_scale=False):# SGBM匹配参数设置if left_image.ndim == 2:img_channels = 1else:img_channels = 3blockSize = 3paraml = {'minDisparity': 0,'numDisparities': 64,'blockSize': blockSize,'P1': 8 * img_channels * blockSize ** 2,'P2': 32 * img_channels * blockSize ** 2,'disp12MaxDiff': 1,'preFilterCap': 63,'uniquenessRatio': 15,'speckleWindowSize': 100,'speckleRange': 1,'mode': cv2.STEREO_SGBM_MODE_SGBM_3WAY}# 构建SGBM对象left_matcher = cv2.StereoSGBM_create(**paraml)paramr = paramlparamr['minDisparity'] = -paraml['numDisparities']right_matcher = cv2.StereoSGBM_create(**paramr)# 计算视差图size = (left_image.shape[1], left_image.shape[0])if down_scale == False:disparity_left = left_matcher.compute(left_image, right_image)disparity_right = right_matcher.compute(right_image, left_image)else:left_image_down = cv2.pyrDown(left_image)right_image_down = cv2.pyrDown(right_image)factor = left_image.shape[1] / left_image_down.shape[1]disparity_left_half = left_matcher.compute(left_image_down, right_image_down)disparity_right_half = right_matcher.compute(right_image_down, left_image_down)disparity_left = cv2.resize(disparity_left_half, size, interpolation=cv2.INTER_AREA)disparity_right = cv2.resize(disparity_right_half, size, interpolation=cv2.INTER_AREA)disparity_left = factor * disparity_leftdisparity_right = factor * disparity_right# 真实视差(因为SGBM算法得到的视差是×16的)trueDisp_left = disparity_left.astype(np.float32) / 16.trueDisp_right = disparity_right.astype(np.float32) / 16.return trueDisp_left, trueDisp_right

深度计算
得到视差图后,计算像素深度值,公式如下:
depth = ( f * baseline) / disp
其中,depth表示深度图;f表示归一化的焦距,也就是内参中的fx; baseline是两个相机光心之间的距离,称作基线距离;disp是视差值
实验直接利用opencv中的cv2.reprojectImageTo3D()函数计算深度图,代码如下

def getDepthMapWithQ(disparityMap: np.ndarray, Q: np.ndarray) -> np.ndarray:points_3d = cv2.reprojectImageTo3D(disparityMap, Q)depthMap = points_3d[:, :, 2]reset_index = np.where(np.logical_or(depthMap < 0.0, depthMap > 65535.0))depthMap[reset_index] = 0return depthMap.astype(np.float32)

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

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

相关文章

SpringBoot基础(五):集成JUnit5

SpringBoot基础系列文章 SpringBoot基础(一)&#xff1a;快速入门 SpringBoot基础(二)&#xff1a;配置文件详解 SpringBoot基础(三)&#xff1a;Logback日志 SpringBoot基础(四)&#xff1a;bean的多种加载方式 SpringBoot基础(五)&#xff1a;集成JUnit5 目录 一、JUnit…

AIGC毕设项目分享:基于RAG的数字人对话系统及其应用

本研究的主要目标是设计并实现一个基于检索增强生成&#xff08;RAG&#xff09;技术的数字人对话系统&#xff0c;旨在提升数字人系统在多轮对话中的上下文管理、情境感知能力以及动态内容生成效果。系统结合了深度学习中的最新大语言模型技术&#xff0c;通过引入RAG框架来增…

K8S配置MySQL主从自动水平扩展

前提环境 操作系统Ubuntu 22.04 K8S 1.28.2集群&#xff08;1个master2个node&#xff09; MySQL 5.7.44部署在K8S的主从集群 metrics-server v0.6.4 概念简介 在K8s中扩缩容分为两种 ●Node层面&#xff1a;对K8s物理节点扩容和缩容&#xff0c;根据业务规模实现物理节点自动扩…

爬虫案例——网易新闻数据的爬取

案例需求&#xff1a; 1.爬取该新闻网站——&#xff08;网易新闻&#xff09;的数据&#xff0c;包括标题和链接 2.爬取所有数据&#xff08;翻页参数&#xff09; 3.利用jsonpath解析数据 分析&#xff1a; 该网站属于异步加载网站——直接网页中拿不到&#xff0c;需要…

MySQL-08.DDL-表结构操作-创建-案例

一.MySQL创建表的方式 1.首先根据需求文档定义出原型字段&#xff0c;即从需求文档中可以直接设计出来的字段 2.再在原型字段的基础上加上一些基础字段&#xff0c;构成整个表结构的设计 我们采用基于图形化界面的方式来创建表结构 二.案例 原型字段 各字段设计如下&…

深入理解线性表--顺序表

目录 顺序表- Seqlist -> sequence 顺序 list 表 顺序表的概念 问题与解答 顺序表的分类 静态顺序表 动态顺序表 问题与解答(递进式) 动态顺序表的实现 尾插 头插 尾删 头删 指定位置插入 指定位置删除 销毁 总结 前言&#xff1a;线性表是具有相同特性的一类数据结构…

2024 年 04 月编程语言排行榜,PHP 排名创新低?

编程语言的流行度总是变化莫测&#xff0c;每个月的排行榜都揭示着新的趋势。2024年4月的编程语言排行榜揭示了一个引人关注的现象&#xff1a;PHP的排名再次下滑&#xff0c;创下了历史新低。这种变化对于PHP开发者和整个技术社区来说&#xff0c;意味着什么呢&#xff1f; P…

现代数字信号处理I-P3 MVUE学习笔记

目录 1. 参数估计问题的提出与本质 2. 估计的性质 2.1 Ancillary&#xff08;多余估计&#xff09; 例1&#xff0c;Ancillary估计量 2. Uniformly Optimal 3. Sufficiency充分性 3.1 统计量充分性定义 例2&#xff1a;利用充分统计量定义获取伯努利分布的充分统计量 …

Anaroute - 理论学习(一)

一、贡献&#xff1a; 框架能够在考虑特定约束的同时&#xff0c;高效地完成复杂AMS设计的布线&#xff0c;并实现签署质量的性能。 提出了一种对称性约束的分配算法&#xff0c;根据引脚位置分配合适的网络匹配要求新的引脚聚类策略&#xff0c;以实现规律性的布线模式&…

微知-Bluefield DPU使用flint烧录固件报错MFE_NO_FLASH_DETECTED是什么?MFE是什么?

文章目录 背景一些报错场景MFE是什么&#xff1f;有哪些MFE 背景 在DPU的fw操作flint的时候&#xff0c;很多命令都会报这个错误&#xff1a;MFE_NO_FLASH_DETECTED&#xff0c;早期很疑惑并且猜测MFE是Mellanox Firmware Engine。实际并不是&#xff0c;具体还得走到mellanox…

2014年国赛高教杯数学建模B题创意平板折叠桌解题全过程文档及程序

2014年国赛高教杯数学建模 B题 创意平板折叠桌 某公司生产一种可折叠的桌子&#xff0c;桌面呈圆形&#xff0c;桌腿随着铰链的活动可以平摊成一张平板&#xff08;如图1-2所示&#xff09;。桌腿由若干根木条组成&#xff0c;分成两组&#xff0c;每组各用一根钢筋将木条连接…

2024 第一次周赛

A: 题目大意 骑士每连续 i 天每天会得到 i 个金币&#xff0c;&#xff08;i 1&#xff0c; 2&#xff0c; 3 &#xff0c; …&#xff09;,那么展开看每一天可以得到的金币数&#xff1a;1 2 2 3 3 3 4 4 4 5 5 5 5 5 … 可以发现就是1个1 &#xff0c;2个2, 3个3…,那么我…

php 生成随机数

记录:随机数抽奖 要求:每次生成3个 1 - 10 之间可重复(或不可重复)的随机数,10次为一轮,每轮要求数字5出现6次、数字4出现3次、…。 提炼需求: 1,可设置最小数、最大数、每次抽奖生成随机数的个数、是否允许重复 2,可设置每轮指定数字的出现次数 3,可设置每轮的抽奖…

一维数组的引用

#define SIZE 5 int main(void) { int i 0; int arr[SIZE] { 86,85,85,896,45 };//同理五个数据只是偶然&#xff0c;可能会更多 //输入 for (i 0;i < SIZE;i) { printf("请输入你的第%d个值&#xff1a;",i1); scanf_s(&…

Spark常用RDD算子:transformation转换算子以及action触发算子

文章目录 1. 算子&#xff08;方法&#xff09;介绍2. 常用transformation算子2.1 map 2.2 flatMap2.3 filter2.4 distinct2.6 groupBy2.7 sortBy()2.8 k-v数据[(k,v),(k1,v1)] 3. 常用action算子 1. 算子&#xff08;方法&#xff09;介绍 rdd中封装了各种算子方便进行计算&a…

【Linux网络编程】网络基础 | Socket 编程基础

&#x1f308;个人主页&#xff1a; 南桥几晴秋 &#x1f308;C专栏&#xff1a; 南桥谈C &#x1f308;C语言专栏&#xff1a; C语言学习系列 &#x1f308;Linux学习专栏&#xff1a; 南桥谈Linux &#x1f308;数据结构学习专栏&#xff1a; 数据结构杂谈 &#x1f308;数据…

【动手学深度学习】6.3 填充与步幅(个人向笔记)

卷积的输出形状取决于输入形状和卷积核的形状在应用连续的卷积后&#xff0c;我们最终得到的输出大小远小于输入大小&#xff0c;这是由于卷积核的宽度和高度通常大于1导致的比如&#xff0c;一个 240 240 240240 240240像素的图像&#xff0c;经过10层 5 5 55 55的卷积后&am…

自然语言处理问答系统:技术进展、应用与挑战

自然语言处理&#xff08;NLP&#xff09;问答系统是人工智能领域的一个重要分支&#xff0c;它通过理解和分析用户的提问&#xff0c;从大量的文本数据中提取相关信息&#xff0c;并以自然语言的形式回答用户的问题。随着深度学习技术的发展&#xff0c;尤其是预训练语言模型&…

MATLAB智能优化算法-学习笔记(4)——灰狼优化算法求解旅行商问题【过程+代码】

灰狼优化算法(Grey Wolf Optimizer, GWO)是一种基于灰狼社会行为的元启发式算法,主要模拟灰狼群体的捕猎行为(包括围攻、追捕、搜寻猎物等过程)。多旅行商问题(Multi-Traveling Salesman Problem, mTSP)是旅行商问题(TSP)的扩展,它涉及多个旅行商(车辆)从一个起点城…

深度学习:循环神经网络—RNN的原理

传统神经网络存在的问题&#xff1f; 无法训练出具有顺序的数据。模型搭建时没有考虑数据上下之间的关系。 RNN神经网络 RNN&#xff08;Recurrent Neural Network&#xff0c;循环神经网络&#xff09;是一种专门用于处理序列数据的神经网络。在处理序列输入时具有记忆性…