双目视觉搭配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_left
    right_K = config.cam_matrix_right
    left_distortion = config.distortion_l
    right_distortion = config.distortion_r
    R = config.R
    T = 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 = 1
    else:
        img_channels = 3
    blockSize = 3
    paraml = {'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 = paraml
    paramr['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_left
        disparity_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] = 0
    return depthMap.astype(np.float32)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【最新华为OD机试E卷-支持在线评测】英文输入法(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)

🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 💻 ACM金牌🏅️团队 | 大厂实习经历 | 多年算法竞赛经历 ✨ 本系列打算持续跟新华为OD-E/D卷的多语言AC题解 🧩 大部分包含 Python / C / Javascript / Java / Cpp 多语言代码 👏 感谢大家的订阅➕ 和 喜欢�…

大数据-158 Apache Kylin 安装配置详解 集群模式启动

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

多态常见面试问题

1、什么是多态&#xff1f; 多态&#xff08;Polymorphism&#xff09;是面向对象编程中的一个重要概念&#xff0c;它允许同一个接口表现出不同的行为。在C中&#xff0c;多态性主要通过虚函数来实现&#xff0c;分为编译时多态&#xff08;静态多态&#xff09;和运行时多态…

Qt事件——鼠标事件

通过label来显示各种事件 鼠标按下事件 //按下显示坐标 void MyLabel::mousePressEvent(QMouseEvent * ev) {int i ev->x();int j ev->y();//判断按下的鼠标键位if (ev->button() Qt::LeftButton) {qDebug() << "LeftButton";}else if (ev->bu…

HAL库常用的函数:

目录 HAL库&#xff1a; 1.GPIO常用函数&#xff1a; 1.HAL_GPIO_ReadPin( ) 2.HAL_GPIO_WritePin( ) 3.HAL_GPIO_TogglePin( ) 4.HAL_GPIO_EXTI_IRQHandler( ) 5.HAL_GPIO_EXTI_Callback( ) 2.UART常用函数&#xff1a; 1.HAL_U…

数通--3

一、动态路由 内部 路由器之间要互联互通&#xff0c;必须遵循相同的协议 企业内部用 IGP&#xff0c;企业之间用BGP RIP&#xff08;已淘汰&#xff0c;不考&#xff09; 距离就是长短&#xff0c;矢量就是方向&#xff0c;即路由的出接口 一台路由器 A 配好RIP&#xff0c;…

JavaWeb 17.过滤器

目录 一、过滤器概述 生活举例&#xff1a;公司前台&#xff0c;停车场安保系统&#xff0c;地铁检票闸机 过滤器开发中应用场景 过滤器工作位置图解 Filter接口API&#xff1a; 二、过滤器过滤过程图解 三、过滤器生命周期 四、过滤器链的使用 工作流程图解 注解方式配置过滤…

map和set(一)

首先模拟一下key形式类 使用的结构是搜索二叉树 结点中有左孩子和右孩子 还有一个存储的值 template <class K>struct BSTnode//搜索二叉树不支持修改 中序遍历是有序的{K _key;BSTnode<K>* _left;BSTnode<K>* _right;BSTnode(const K& key):_key(key…

网络资源模板--Android Studio 实现记事本App

目录 一、项目演示 二、项目测试环境 三、项目详情 四、完整的项目源码 一、项目演示 网络资源模板--基于Android studio 实现的记事本App 二、项目测试环境 三、项目详情 首页 显示笔记列表&#xff1a;使用 ListView 显示从数据库中查询到的笔记内容。搜索功能&#xff…

web-105linux权限提升

rsync未授权本地覆盖 Rsync 是 linux 下一款数据备份工具&#xff0c;默认开启 873 端口 https://vulhub.org/#/environments/rsync/common/ 借助 Linux 默认计划任务调用/etc/cron.hourly&#xff0c;利用 rsync 连接覆盖 前提条件就是需要知道rsync的密码或者存在未授权 -提…

Java微信支付接入(6) - API V3 Native 支付通知API

官方文档&#xff1a;https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_5.shtml 通知规则&#xff1a;用户支付完成后&#xff0c;微信会把相关支付结果和用户信息发送给商户&#xff0c;商户需要接收处理该消息&#xff0c;并返回应答。对后台通知交互时&#xff0c…

如何解决 Vim 中的 “E212: Can‘t open file for writing“ 错误:从编辑到权限管理(sudo)

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…

第十五届蓝桥杯C++B组省赛

文章目录 1.握手问题解题思路1&#xff08;组合数学&#xff09;解题思路2&#xff08;暴力枚举&#xff09; 2.小球反弹做题思路 3.好数算法思路&#xff08;暴力解法&#xff09;---不会超时 4.R格式算法思路 5.宝石组合算法思路---唯一分解定理 6.数字接龙算法思路----DFS 7…

TinyOS 点对基站通信

文章目录 一、前言1.1 发包的BlinkToRadio的数据包格式 二、混淆基站源码分析2.1 Makefile2.2 组件连接2.3 主逻辑代码 一、前言 1.1 发包的BlinkToRadio的数据包格式 如下&#xff0c;注意&#xff1a;AM层类型(1byte)即handlerID使可以在组件中修改的。 二、混淆基站源码…

uniapp学习(004-1 组件 Part.2生命周期)

零基础入门uniapp Vue3组合式API版本到咸虾米壁纸项目实战&#xff0c;开发打包微信小程序、抖音小程序、H5、安卓APP客户端等 总时长 23:40:00 共116P 此文章包含第31p-第p35的内容 文章目录 组件生命周期我们主要使用的三种生命周期setup(创建组件时执行)不可以操作dom节点…

使用 three.js和 shader 实现一个五星红旗 飘扬得着色器

使用 three.js和 shader 实现一个五星红旗 飘扬得着色器 源链接&#xff1a;https://threehub.cn/#/codeMirror?navigationThreeJS&classifyshader&idchinaFlag 国内站点预览&#xff1a;http://threehub.cn github地址: https://github.com/z2586300277/three-ce…

python异常检测 - 随机离群选择Stochastic Outlier Selection (SOS)

python异常检测 - Stochastic Outlier Selection (SOS) 前言 随机离群选择SOS算法全称stochastic outlier selection algorithm. 该算法的作者是jeroen janssens. SOS算法是一种无监督的异常检测算法. 随机离群选择SOS算法原理 随机离群选择SOS算法的输入: 特征矩阵(featu…

【代码】集合set

哈喽大家好&#xff0c;我是学霸小羊&#xff0c;今天来讲一讲集合&#xff08;set&#xff09;。 在数学上&#xff0c;集合长这样&#xff1a; 那今天就来讲一讲编程上的集合。 集合的定义&#xff1a;把一些元素按照某些规律放在一起&#xff0c;就形成了一个集合。比如说…

stm32单片机个人学习笔记10(TIM编码器接口)

前言 本篇文章属于stm32单片机&#xff08;以下简称单片机&#xff09;的学习笔记&#xff0c;来源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记&#xff0c;只能做参考&#xff0c;细节方面建议观看视频&#xff0c;肯定受益匪浅。 STM32入门教程-2023版 细…

论文笔记:Template-Based Named Entity Recognition Using BART

论文来源&#xff1a;ACL 2021 Finding 论文链接&#xff1a;https://aclanthology.org/2021.findings-acl.161.pdf 论文代码&#xff1a;GitHub - Nealcly/templateNER: Source code for template-based NER 笔记仅供参考&#xff0c;撰写不易&#xff0c;请勿恶意转载抄袭…