当前位置: 首页 > news >正文

双目视觉:reprojectImageTo3D函数

前言

reprojectImageTo3D 是 OpenCV 中用于从视差图生成三维点云的函数。它的原理是利用视差图和相机的校准参数,通过三角测量法,计算每个像素对应的三维坐标。以下内容根据源码分析所写,觉得可以的话,点赞收藏哈!!

一、基础知识

齐次坐标:齐次坐标是一种数学表示方法,它在计算机图形学和计算机视觉中被广泛使用,特别是在处理3D空间中的点和变换时。齐次坐标的主要作用有以下几点:

  • 统一表示:齐次坐标允许我们使用一个统一的表示方法来处理点和向量。在笛卡尔坐标系中,点和向量是不同的概念,但通过引入齐次坐标,我们可以将它们表示为相同的形式。例如,一个3D点(x,y,z)可以表示为齐次坐标(x,y,z,1),而一个3D向量(a,b,c)可以表示为齐次坐标(a,b,c,0)。
  • 简化变换:齐次坐标简化了3D空间中的线性变换,如旋转、平移和缩放。在笛卡尔坐标系中,平移不能通过矩阵乘法来表示(矩阵大小💥💥💥),但通过引入齐次坐标,平移可以表示为一个4x4矩阵与齐次坐标向量的乘法。例如,一个平移变换T=(tx​,ty​,tz​)可以表示为以下矩阵:

视差图:在立体视觉系统中,两个相机(称为立体相机)被放置在一定的距离(称为基线)上,同时拍摄同一场景。由于两个相机的位置不同,它们拍摄到的同一物体在两个图像中的位置会有所不同。这种位置差异就是视差(Xr-Xl💥💥💥)。视差图的大小等于图像大小,最大值为1024,最小值为0。

二、推导过程

(1)双目相机的坐标系

在双目视觉中,两个相机的几何模型如下:

  • 左相机的光心位于原点 [0,0,0]其像平面位于 Z=f。 
  • 右相机的光心位于 [Tx,0,0],即两个相机光心的水平基线距离为 Tx​。 
  • 像素点 (x,y) 是在左图像的像素坐标系中的位置,d=xleft−xright是视差。

(2)齐次坐标的引入

为了方便将像素坐标 (x,y)和视差 d直接映射到三维空间,引入齐次坐标系。齐次坐标将三维点扩展为四维表示:[X, Y, Z, W]。其中, [X/W,Y/W,Z/W]是三维坐标,W 是归一化因子。重点内容哈! 仅此一家哈!!💥💥💥

(3)数学公式

使用重投影矩阵 Q 与齐次坐标(x,y,d,1) 进行矩阵乘法。这一步将2D点转换为3D空间中的一个点。将得到的4维向量(X,Y,Z,W) 归一化,即除以 W 分量,得到3D空间中的点(X/W,Y/W,Z/W)。

三、源码

void cv::reprojectImageTo3D( InputArray _disparity,OutputArray __3dImage, InputArray _Qmat,bool handleMissingValues, int dtype )
{CV_INSTRUMENT_REGION();Mat disparity = _disparity.getMat(), Q = _Qmat.getMat();int stype = disparity.type();CV_Assert( stype == CV_8UC1 || stype == CV_16SC1 ||stype == CV_32SC1 || stype == CV_32FC1 );CV_Assert( Q.size() == Size(4,4) );if( dtype >= 0 )dtype = CV_MAKETYPE(CV_MAT_DEPTH(dtype), 3);if( __3dImage.fixedType() ){int dtype_ = __3dImage.type();CV_Assert( dtype == -1 || dtype == dtype_ );dtype = dtype_;}if( dtype < 0 )dtype = CV_32FC3;elseCV_Assert( dtype == CV_16SC3 || dtype == CV_32SC3 || dtype == CV_32FC3 );__3dImage.create(disparity.size(), dtype);Mat _3dImage = __3dImage.getMat();const float bigZ = 10000.f;Matx44d _Q;Q.convertTo(_Q, CV_64F);int x, cols = disparity.cols;CV_Assert( cols >= 0 );std::vector<float> _sbuf(cols);std::vector<Vec3f> _dbuf(cols);float* sbuf = &_sbuf[0];Vec3f* dbuf = &_dbuf[0];double minDisparity = FLT_MAX;// NOTE: here we quietly assume that at least one pixel in the disparity map is not defined.// and we set the corresponding Z's to some fixed big value.if( handleMissingValues )cv::minMaxIdx( disparity, &minDisparity, 0, 0, 0 );for( int y = 0; y < disparity.rows; y++ ){float* sptr = sbuf;Vec3f* dptr = dbuf;if( stype == CV_8UC1 ){const uchar* sptr0 = disparity.ptr<uchar>(y);for( x = 0; x < cols; x++ )sptr[x] = (float)sptr0[x];}else if( stype == CV_16SC1 ){const short* sptr0 = disparity.ptr<short>(y);for( x = 0; x < cols; x++ )sptr[x] = (float)sptr0[x];}else if( stype == CV_32SC1 ){const int* sptr0 = disparity.ptr<int>(y);for( x = 0; x < cols; x++ )sptr[x] = (float)sptr0[x];}elsesptr = disparity.ptr<float>(y);if( dtype == CV_32FC3 )dptr = _3dImage.ptr<Vec3f>(y);for( x = 0; x < cols; x++){double d = sptr[x];Vec4d homg_pt = _Q*Vec4d(x, y, d, 1.0);dptr[x] = Vec3d(homg_pt.val);dptr[x] /= homg_pt[3];if( fabs(d-minDisparity) <= FLT_EPSILON )dptr[x][2] = bigZ;}if( dtype == CV_16SC3 ){Vec3s* dptr0 = _3dImage.ptr<Vec3s>(y);for( x = 0; x < cols; x++ ){dptr0[x] = dptr[x];}}else if( dtype == CV_32SC3 ){Vec3i* dptr0 = _3dImage.ptr<Vec3i>(y);for( x = 0; x < cols; x++ ){dptr0[x] = dptr[x];}}}
}

四、总结

像素坐标到三维点

  • 像素坐标 (x,y)和视差 d 提供了物体的二维位置和深度信息。 
  • 重投影矩阵 Q将这些信息通过矩阵运算映射到三维空间。 

视差与深度关系

  • 视差 d 越大,深度 Z 越小(物体越近。 
  • 齐次坐标中的 W 用于归一化三维坐标。

相关文章:

双目视觉:reprojectImageTo3D函数

前言 reprojectImageTo3D 是 OpenCV 中用于从视差图生成三维点云的函数。它的原理是利用视差图和相机的校准参数&#xff0c;通过三角测量法&#xff0c;计算每个像素对应的三维坐标。以下内容根据源码分析所写&#xff0c;觉得可以的话&#xff0c;点赞收藏哈&#xff01;&am…...

Arduino Uno简介与使用方法

目录 一、Arduino Uno概述 1. 硬件特性 2. 开发环境 二、Arduino Uno的基本使用方法 1. 硬件连接 2. 软件编程 三、Arduino Uno编程基础 1. 基本语法 2. 常用函数 四、Arduino Uno应用举例 1. LED闪烁 2. 温度检测 3. 超声波测距 五、Arduino Uno的扩展与应用 1…...

深入了解 StarRocks 表类型:解锁高效数据分析的密码

在当今数字化浪潮下&#xff0c;大数据分析成为企业决策、优化业务流程的关键利器。StarRocks 作为一款备受瞩目的高性能分析型数据库&#xff0c;其多样化的表类型为复杂的数据处理需求提供了精准解决方案。今天&#xff0c;就让我们一同深入探索 StarRocks 中的主键表、明细表…...

L27.【LeetCode笔记】2 的幂(五种解法)

目录 1.题目 2.自解 方法1:调用log函数 代码 提交结果 方法2:循环 提交结果 3.优解 方法3:位运算n & (n-1) 0 代码 提交结果 方法4:位运算lowbit 代码 提交结果 4.投机取巧的方法 代码 提交结果 1.题目 https://leetcode.cn/problems/power-of-two/?env…...

Pentaho Kettle迁移至Oracle的空字符串和NULL的问题处理,大坑!

一、问题说明 在使用 Kettle 将 DB2 数据迁移到 Oracle 的过程中&#xff0c;出现了 DB2 中为空字符串的字段&#xff0c;在插入到 Oracle 过程中实际插入的为 NULL &#xff0c;导致触发了非空校验而迁移失败 空字符串 ‘’ &#xff0c;即长度为0的字符串 搜索该问题后得知…...

「Mac畅玩鸿蒙与硬件50」UI互动应用篇27 - 水果掉落小游戏

本篇教程将带你实现一个水果掉落小游戏&#xff0c;掌握基本的动态交互逻辑和鸿蒙组件的使用&#xff0c;进一步了解事件处理与状态管理。 关键词 UI互动应用水果掉落状态管理动态交互游戏开发 一、功能说明 水果掉落小游戏包含以下交互功能&#xff1a; 随机生成水果&#…...

2.C语言基础:语句、表达式、注释与标准库简介

目录 1.语句2.表达式3.语句块4.空格5.注释6.printf()7.标准库 本篇原文为&#xff1a;C语言基础&#xff1a;语句、表达式、注释与标准库简介 更多C进阶、rust、python、逆向等等教程&#xff0c;可点击此链接查看&#xff1a;酷程网 1.语句 C 语言的代码由一行行语句&#…...

Python 基于 opencv 的人脸识别监控打卡系统(源码+部署)

1. 引言 今天&#xff0c;我们将基于 Python 的 OpenCV 库和 wxPython 框架&#xff0c;构建一个实用的 人脸识别考勤系统。这是一个适合大学生学习的实战项目&#xff0c;功能经过充分调试&#xff0c;确保运行稳定。该系统不仅能帮助你了解人脸识别技术的基本原理&#xff0…...

Maven的依赖管理

1. 依赖管理 依赖管理&#xff0c;可以将有关依赖项的所有信息放在共同的POM中&#xff0c;并对子POM中的工件进行更简单的引用。举个例子&#xff1a; 父POM <project>......<dependencyManagement><dependencies><dependency><groupId>gro…...

数据结构考前一天

线性表&#xff1a;矩阵&#xff0c;链表&#xff08;单链表必考&#xff09; 栈和队列&#xff1a;出入判断&#xff0c;括号匹配&#xff0c;中缀转后缀 字符串数组&#xff1a;模式匹配next&#xff0c;nextval数组&#xff0c;数组寻址&#xff0c;三角矩阵对应一维数组k…...

获取 Astro Bot AI 语音来增强您的游戏体验!

有很多用户尝试过Astro Bot&#xff0c;却被Astro Bot可爱的声音所吸引。您是否想知道如何使用 Astro Bot 语音来拨打恶作剧电话或用他的声音说话&#xff1f;如果您有&#xff0c;那么这篇文章适合您。我们将向您展示如何为 Astro Bot 提供逼真的 AI 声音并在在线对话中使用它…...

html5开发,js 在元素div id=img1的最前面插入一个图片

在 JavaScript 中&#xff0c;你可以使用 document.createElement 来创建一个新的图片元素&#xff0c;然后使用 document.getElementById 来获取目标 div 元素&#xff0c;并使用 appendChild 方法将新创建的图片元素插入到 div 的最前面。不过&#xff0c;appendChild 方法会…...

Elasticsearch Serverless中的数据流自动分片深度解析

Elasticsearch Serverless中的数据流自动分片深度解析 一、Elasticsearch Serverless概述 1. 什么是Elasticsearch Serverless Elasticsearch Serverless是一种云端全托管的Elasticsearch服务&#xff0c;它基于云原生Serverless技术架构&#xff0c;提供自动弹性和完全免运…...

2025考研江南大学复试科目控制综合(初试807自动控制原理)

​ 2025年全国硕士研究生招生考试江南大学考点 一年年的考研如期而至&#xff0c;我也变成了研二了&#xff0c;作为2次考研经历的学长&#xff0c;总是情不自禁地回想起自己的考研经历&#xff0c;我也会经常从那段经历中汲取力量。我能理解大多数考生考完后的的迷茫无助&…...

Elasticsearch分片数量是什么意思?

Elasticsearch中的分片&#xff08;Shard&#xff09;数量是一个重要概念&#xff0c;以下为你详细介绍它的含义及相关要点&#xff1a; ### 定义 分片是Elasticsearch将索引数据进行拆分的基本单元。简单来说&#xff0c;Elasticsearch会把一个索引的数据分割成多个较小的部分…...

PWN的知识之栈溢出

栈溢出 什么是栈溢出&#xff1f; 栈溢出&#xff08;Stack Overflow&#xff09;是指在程序运行过程中&#xff0c;向栈中存放的数据量超过了栈的最大容量&#xff0c;从而导致程序出现异常行为的情况。可以比作一个箱子原本只能容纳一定数量的物品&#xff0c;如果强行往里…...

java.lang.Error: FFmpegKit failed to start on brand:

如果你使用FFmpegKit的时候遇到了这个问题&#xff1a; java.lang.Error: FFmpegKit failed to start on brand: Xiaomi, model: MI 8, device: dipper, api level: 29, abis: arm64-v8a armeabi-v7a armeabi, 32bit abis: armeabi-v7a armeabi, 64bit abis: arm64-v8a.at c…...

TCPDump参数详解及示例

TCPDump参数详解及示例 TCPDump参数详解TCPDump -G的示例TCPDump -i any -s 2048 -G 600 -p udp -Z root -n -X -tt -w %Y_%m%d_%H%M_%S.pcap &的含义TCPDump是一款强大的网络数据包截获分析工具,可以将网络中传送的数据包的完全截获下来提供分析。它支持针对网络层、协议…...

Spring如何实现管理事务

目录 简介&#xff1a; 分类&#xff1a; 1.编程式事务管理&#xff1a; 2. 声明式事务管理&#xff1a; 3.事务传播和隔离级别&#xff1a; 配置 Spring 事务管理&#xff1a; 总结&#xff1a; 简介&#xff1a; Spring 通过事务管理器&#xff08;Transaction Manager…...

windows C#-接口中的索引器

可以在接口上声明索引器。 接口索引器的访问器与类索引器的访问器有所不同&#xff0c;差异如下&#xff1a; 接口访问器不使用修饰符。接口访问器通常没有正文。 访问器的用途是指示索引器为读写、只读还是只写。 可以为接口中定义的索引器提供实现&#xff0c;但这种情况非…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...

从面试角度回答Android中ContentProvider启动原理

Android中ContentProvider原理的面试角度解析&#xff0c;分为​​已启动​​和​​未启动​​两种场景&#xff1a; 一、ContentProvider已启动的情况 1. ​​核心流程​​ ​​触发条件​​&#xff1a;当其他组件&#xff08;如Activity、Service&#xff09;通过ContentR…...

OD 算法题 B卷【正整数到Excel编号之间的转换】

文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的&#xff1a;a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...