双目立体视觉三维重构总结

2023-10-27


前面多多少少记录一些相关知识,由于相关工作还在继续,加上网上的教程总不是十分完善。这里做一个总结,希望自己能够加深对这个过程的整体的理解与认识。

基本步骤

  1. 相机标定
  2. 图片采集
  3. 立体校正
  4. 匹配算法
  5. 三维重构
  6. 点云去噪
  7. 点云显示

相机标定

使用的Matlab标定工具箱,需要注意的点有:

  1. 每个相机单独标定,之后再标定双目相机的位姿
  2. 标定单目时需要选择畸变个数,一般如果不是鱼眼镜头,只需要标定两个径向畸变、两个切向畸变。
  3. 图像采集,和标定精度测试移步这里
  4. Matlab标定参数用于opencv移步这里

图像采集

我使用的非常基础的USB双目相机,两个相机之间居然还存在色差。。。videoCapture就可以了

立体校正

立体校正对于双目的最主要的目的是为稠密匹配算法提供便利。opencv中有具体的立体校正函数

stereoRectify(cameraMatrixL, distCoeffL, cameraMatrixR, distCoeffR,
		imageSize, R, T, Rl, Rr, Pl, Pr, Q, CALIB_ZERO_DISPARITY,
		0, imageSize, &validROIL, &validROIR);
	//再采用映射变换计算函数initUndistortRectifyMap得出校准映射参数,该函数功能是计算畸变矫正和立体校正的映射变换
	initUndistortRectifyMap(cameraMatrixL, distCoeffL, Rl, Pl(Rect(0, 0, 3, 3)),
		imageSize, CV_32FC1, mapLx, mapLy);
	initUndistortRectifyMap(cameraMatrixR, distCoeffR, Rr, Pr(Rect(0, 0, 3, 3)),
		imageSize, CV_32FC1, mapRx, mapRy);
	remap(grayImageL, rectifyImageL, mapLx, mapLy, INTER_LINEAR);
	remap(grayImageR, rectifyImageR, mapRx, mapRy, INTER_LINEAR);//立体校正完成的图片即保存在rectifyImageL/R中

匹配算法

使用SGM算法计算左目视差,其实为了增加准确程度,也会计算右目的视差用于补偿左目视差。但是为了实时性,在这里只计算了左目视差。我自己学习了SGM算法的源代码,也可以使用opencv自带的函数,具体如何使用网上教程很多很多,这里只给出一个示例:

cv::Ptr<cv::StereoSGBM> sgbm = StereoSGBM::create(0, 16, 3);	
sgbm->setPreFilterCap(63);
	int SADWindowSize = 5;
	int sgbmWinSize = SADWindowSize > 0 ? SADWindowSize : 3;
	sgbm->setBlockSize(sgbmWinSize);
	int cn = rectifyImageL.channels();
	sgbm->setP1(8 * cn*sgbmWinSize*sgbmWinSize);
	sgbm->setP2(32 * cn*sgbmWinSize*sgbmWinSize);
	sgbm->setMinDisparity(0);
	sgbm->setNumDisparities(numberOfDisparities);
	sgbm->setUniquenessRatio(10);
	sgbm->setSpeckleWindowSize(100);
	sgbm->setSpeckleRange(1);
	sgbm->setDisp12MaxDiff(1);
	sgbm->setMode(cv::StereoSGBM::MODE_SGBM);
	sgbm->compute(rectifyImageL,//250, 100, 250, 100;150, 100, 400, 300
		rectifyImageR, disp);

三维重构

我只想说,opencv挺好用

	disp.convertTo(disp8, CV_32F, 255 / (numberOfDisparities * 16.));	//1.0/16计算出的视差是CV_16S格式 CV_32F, 255 / ((numDisparities * 16 + 16)*16.) 255 / (numberOfDisparities*16.) 
	reprojectImageTo3D(disp8, xyz, Q, true);//Q是之前立体校正得到的参数计算3D点云保存在xyz中

点云去噪

在上述过程中获得了稠密点的坐标xyz,将其赋值给点云,使用点云滤波即可去噪。PCL点云库的使用移步这里

void two_Eyes::cal_cloud(int disflag)
{
	double plane[3];
	mutex1.lock();
	param_3D.xyz.copyTo(xyz);
	plane[0] = param_3D.plane[0];
	plane[1] = param_3D.plane[1];
	plane[2] = param_3D.plane[2];
	mutex1.unlock();	
	double fenmu = sqrt(powf(plane[0], 2) + powf(plane[1], 2) + 1);
	double Wx, Wy, Wz;
	vector<double>().swap(dis);			//清楚dis中的内容


	double t_c = (double)clock();
	cvtColor(rectifyImageL, rectifyImageL, CV_GRAY2RGB);
	int rowNumber = rectifyImageL.rows;
	int colNumber = rectifyImageL.cols;
	pcl::PointCloud<pcl::PointXYZRGB> cloud_a2,cloud_a3;
	cloud_a2.height = rowNumber;
	cloud_a2.width = colNumber;
	cloud_a2.points.resize(colNumber* rowNumber);
	for (unsigned int u = 0; u < rowNumber; ++u)
	{
		for (unsigned int v = 0; v < colNumber; ++v)
		{
			/*unsigned int num = rowNumber*colNumber-(u*colNumber + v)-1;*/
			unsigned int num = u * colNumber + v;
			cloud_a2.points[num].b = rectifyImageL.at<Vec3b>(u, v)[0];
			cloud_a2.points[num].g = rectifyImageL.at<Vec3b>(u, v)[1];
			cloud_a2.points[num].r = rectifyImageL.at<Vec3b>(u, v)[2];
			
			double Xw = 0, Yw = 0, Zw = 0;
			if (xyz.at<Vec3f>(u, v)[2] < 1000&& xyz.at<Vec3f>(u, v)[2]!=0)					//使用OpenCV计算的结果,感觉更加准确
			{
				Wx= xyz.at<Vec3f>(u, v)[0]; 
				Wy= xyz.at<Vec3f>(u, v)[1]; 
				Wz= xyz.at<Vec3f>(u, v)[2];
				cloud_a2.points[num].x = Wx/1000;
				cloud_a2.points[num].y = Wy/1000;
				cloud_a2.points[num].z = Wz/1000;
					
			}
			
			


		}
	}

///滤波示例
	 创建pcl::StatisticalOutlierRemoval滤波器对象
	//pcl::StatisticalOutlierRemoval<pcl::PointXYZRGB> sor;
	//sor.setInputCloud(cloud_a2.makeShared());
	//sor.setStddevMulThresh(1.0);
	将标准差倍数设为1,意味着超过一点的距离超出平均距离一个标准差以上,
	则该点被标记为离群点,将被移除。
	//sor.filter(cloud_a3);  //滤波结果存储于此 
	
	
	
	
	mutex1.lock();
	param_3D.cloud_a = cloud_a2;
	mutex1.unlock();
	cloud_test.close();
	
}

点云显示

可以直接使用PCL库
我是在QT界面上使用VTK显示的点云,这里涉及到更多的QT界面的基础知识,不再赘述
结果如图:
在这里插入图片描述
点云示例:
在这里插入图片描述
在这里插入图片描述

总结

细心可以避免很多小错误
不怕自己做不好,就怕自己停止尝试

由于相机编号0,1和左右不一定是对应的,所以一定要搞清楚再运行算法,别问我是咋知道的~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

双目立体视觉三维重构总结 的相关文章

  • DirectX Release 构建可以通过 VS2010 运行,但不能运行 exe

    我已经通过 Google 访问 Stack Overflow 几年了 但到目前为止还没有询问 回答任何问题 所以就到这里吧 基本上 我有一个在 DirectX 11 中设置绘图模型和地形的 3D 渲染框架 一切正常 通过 Visual St
  • 对一系列点重新采样

    我有一个 3d 点数组 想象一下球的轨迹 有 X 个样本 现在 我想对这些点重新采样 以便我有一个新数组 其中包含 y 个样本的位置 y 可以大于或小于 x 但不能小于 1 始终至少有 1 个样本 将原始数组重新采样为新数组的算法会是什么样
  • Direct3D 中的矩阵多阶

    关于在 Direct3D 中乘法矩阵以获得结果 我收到了两个相互矛盾的答案 教程确实规定从左到右相乘 这很好 但这不是我想象的方式 这是一个例子 OpenGL 从上到下阅读 GLRotatef 90 0f GLTranslatef 20 0
  • OpenGL Z 偏置(多边形偏移)限制

    我有两个共面的多边形 我尝试做 glEnable GL POLYGON OFFSET FILL glPolygonOffset 0 1 并期望其中一个明显 位于 另一个之上 这种情况直到大约 70 75 个单位之外 近剪裁平面为 1 远剪裁
  • 如何将 3D 图像输出到 3D 电视?

    我有一台 3D 电视 如果我不至少尝试让它显示我自己创作的漂亮 3D 图像 我就会逃避我的责任 作为一个极客 我之前已经完成了非常基本的 OpenGL 编程 因此我了解所涉及的概念 假设我可以为自己渲染一个简单的四面体或立方体并使其旋转一点
  • 在 Three.js 中将贝塞尔曲线转换为平面道路

    我试图根据之前计算得到的一些贝塞尔曲线在 Three js 中绘制一条弯曲的道路 问题是我找不到转换曲线序列的方法 一条从上一条曲线的末尾开始 到一个曲面 我有一个 3D 场景 其中有一些汽车 一条用飞机创建的道路 并且绘制了即将到来的道路
  • OpenGL z轴指向哪里?

    我正在尝试了解 OpenGL 坐标系 我到处都看到它被描述为右撇子 但这与我的经验不符 我尝试绘制一些形状和 3 d 对象 我发现 z 轴显然指向 屏幕 而 x 指向右侧 y 指向上方 这是左手坐标系的描述 我缺少什么 编辑 例如 http
  • C++ Irrlicht 程序未链接:“未定义对‘__imp_createDevice’的引用”

    我的 Irrlicht 程序无法链接 我使用的编译器是g Code include
  • 如何在 GTX 560 及更高版本上使用 OpenGL 进行立体 3D?

    我正在使用在 Windows 7 上运行的开源触觉和 3D 图形库 Chai3D 我重写了该库以使用 Nvidia nvision 执行立体 3D 我将 OpenGL 与 GLUT 一起使用 并使用 glutInitDisplayMode
  • 我应该如何格式化 .dat 文件以便制作 3D 矢量图?

    我正在为大学做这个编程任务 我们必须写一个c 计算 3D 空间中某些线圈的磁场矢量的程序 我已经成功编写了这个程序 并且我认为它运行得很好 不过 我想添加一个特殊的东西 这是我的试卷 所以它必须特别好 我想绘制出向量 我习惯打电话gnupl
  • 更改 3D 图形颜色 (matplotlib)

    我使用以下代码在 matplotlib 中绘制了 3D 图形 Previously defines lists of data to plot fig plt figure ax fig add subplot 111 projection
  • 如何在 React Native 中渲染自定义 3D 对象

    我已经成功使用 Three js expo Three 和 expo gl 在 React Native 中配置了红色立方体的 3D 渲染 但我想让用户渲染他们自己可能拥有的自定义 3D 对象 obj 或 mtl 扩展名 但我不确定如何让他
  • 如何将平面上的 3D 点转换为 UV 坐标?

    我有一个 3d 点 定义为 x0 y0 z0 该点属于一个平面 定义为 a b c d normal a b c and ax by cz d 0 如何将 3d 点转换或映射为一对 u v 坐标 这一定是非常简单的事情 但我无法弄清楚 首先
  • 如何计算正切和副法线?

    谈谈OpenGL着色语言 GLSL 中的凹凸贴图 镜面高光之类的东西 I have 顶点数组 例如 0 2 0 5 0 1 0 2 0 4 0 5 法线数组 例如 0 0 0 0 1 0 0 0 1 0 0 0 世界空间中点光源的位置 例如
  • 使用开源 3D 引擎从 Openstreetmap 数据渲染地图? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 从 Openstreetmap 数据渲染 3D 地图可能会很漂亮麻烦的 https gis stack
  • 求截头棱锥体/截棱锥体横截面的边长

    如何找到横截面的边长 如图所示 下图 横截面 红色 截头锥体 截棱锥体 我知道顶部和底部的边长 以及底部的高度 截锥体和到横截面的距离 此外我还知道 顶部和底部底座平行 并且顶部和底部的中心 底部底座直接位于彼此之上 比例是线性的 因此只需
  • Java 的 3D 场景图库?

    我正在寻找一个可靠的 Java 3D 场景图 API 它具有良好的文档 活跃的社区和允许商业使用的许可证 我排除了com sun scenegraph https scenegraph dev java net 因为它是 GPL 而且看起来
  • React-Three-Fiber:JSON 中位置 3 出现意外标记 c 错误

    我正在尝试使用 React Three Fiber 加载 glb 文件 但出现以下错误 Error Unexpected token c in JSON at position 3 我不确定我做错了什么 看来此问题最常见的解决方案是将 gl
  • 关于Marching Cubes算法的澄清

    关于Marching Cubes 我对其算法和实现有一些疑问 我已经阅读了 Marching Cubes 的 Paul Bourke 优秀文章以及网站上可用的源代码 但是 我在理解以及如何以自己的方式实现算法方面仍然遇到了一些问题 问题如下
  • 3D 图形批处理

    很多网站 文章都说 批量 批 批 有人可以解释一下着色器中的 批处理 代表什么吗 即 是否 改变纹理 更改任意着色器变量 意味着某些东西不能 批处理 最简单的总结方法就是尝试尽可能少地调用 API 来绘制您需要绘制的内容 使用顶点数组或 V

随机推荐

  • 将图像上雨水去除的四种主流方法

    http blog csdn net whyymlm article details 76999469 对图片或者视频进行去噪的研究一直以来都是计算机视觉和图像处理领域内的一个重要课题 在现实生活中 因为雨雪会对道路上的路况造成一定程度的遮
  • 程序员兼职接私活平台大全,兼职也能月薪上万

    前言 PS 如有需要Python学习资料的小伙伴可以加点击下方链接自行获取 CSDN大礼包 python兼职资源 全套学习资料 免费分享 安全链接 放心点击 根据我们的经验 程序员兼职主要分为三种 兼职职位众包 项目整包和自由职业者驻场 我
  • C++14变量模板

    如果对模板或者C 标准感兴趣的开发者们相信都不会对变量模板感到陌生 我们今天就讲一讲变量模板 从C 14 开始 变量也可以被某种类型参数化 称为变量模板 例如可以通过下面的代码定义pi 但是参数化了其类型 template
  • Kaggle竞赛题目之——Digit Recognizer

    Classify handwritten digits using the famous MNIST data This competition is the first in a series of tutorial competitio
  • 代码随想录刷题笔记3

    文章目录 回溯 细节 模板 题型 组合 分割 子集 排列 棋盘问题 N皇后问题 解数独问题 其他 总结 回溯 本质上 穷举 剪枝 回溯法就是解决这种k层for循环嵌套的问题 for循环横向遍历 递归纵向遍历 回溯不断调整结果集 注意画出 解
  • JavaScript闭包

    h2 span style font weight normal background color rgb 192 192 192 span style font size 18px 1 什么是闭包 span span h2 h4 span
  • RabbitMQ--基础--8.2--消息确认机制--发布确认机制

    RabbitMQ 基础 8 2 消息确认机制 发布确认机制 代码位置 https gitee com DanShenGuiZu learnDemo tree master rabbitMq learn rabbitMq 03 1 发布确认原
  • 空间相关分析(二) 全局莫兰指数的理解与计算

    在了解空间权重矩阵的相关知识后 再展开对空间相关分析的学习就会变得轻松许多 而在空间相关分析中 全局相关分析和局部相关分析是比较常用的两个方法 今天 就来分享一下全局相关分析的有关知识 目录 一 公式说明 二 深入理解 三 Moran I指
  • 投资理财笔记——以贴现的方式看待基金

    文章目录 DDM DCF 避免空中楼阁 DDM 关于DDM的相关知识 我在股票价值分析中写过 DDM模型认为股票价值决定于分红而不是未来的股价 而在基金购买中 我认为不可以盲目崇拜于分红 也就是基金的累计净值和净值之差 因为分红势必会出售部
  • Relational Learning with Gated and Attentive Neighbor Aggregator for Few-Shot Knowledge Graph Comple...

    小样本知识图补全 关系学习 利用三元组的邻域信息 提升模型的关系表示学习 来实现小样本的链接预测 主要应用的思想和模型包括 GAT TransH SLTM Model Agnostic Meta Learning MAML 论文地址 htt
  • Java8新特性

    可以利用 List 的 sort 方法进行排序 Comparator comparing 可以指定排序字段 thenComparing 可以继续指定其他的排序字段 默认使用正序排列 如果想倒序可以使用 Comparator reverseO
  • 人工智能与营销新纪元 2023 AI+

    人工智能是什么 有望飞跃式提升营销生产力的变革力量 人工智能是研究 开发用于模拟 延伸和扩展人的智能的理论 方法 技术及应用系统的一门新的 技术科学 是计算机科学的一个分支 它企图了解智能的实质 并生产出一种新的能以人类智能相 似的方式做出
  • macOS和谐安装Office 2021

    声明 和谐 PJ 安装Office 2021 仅用于学习研究使用 不能作为办公用途 本人概不负法律责任 简介 Microsoft Office 2021是Microsoft推出的办公软件 2021年10月5日 Office 2021 for
  • This call to matplotlib.use() has no effect because the backend has alreadybeen chosen

    遇到这个咋办 方法 将 matplotlib use Agg 改为 plt switch backend agg 大吉大利
  • AF_XDP socket 测试

    本篇是之前博客 1 的进阶篇 博客中给出了相关环境安装配置 功能 本篇通过bpf程序 将icmp数据包重定向到AF XDP socket 内核侧程序片断 xdpsock kern c SPDX License Identifier GPL
  • 如何在windows电脑端添加本地环回网卡loopback网络适配器

    电脑端添加本地环回网卡loopback网络适配器 在使用vmware workstation虚拟机或ENSP等网络模拟器等工具时 经常需要绑定多个电脑网卡来进行实验 但电脑中物理网卡有限 此时可通过添加本地环回网卡来解决相关问题 1 桌面单
  • Mysql中的七种常用查询连接详解

    目录 一 概述 二 连接查询的分类 三 七种常用连接查询详解 1 笛卡尔积 2 内连接 2 1隐式与显式连接 2 2等值连接 2 3非等值连接 2 4自连接 3外连接 3 1左外连接 3 2右外连接 3 3全外连接 一 概述 在实际开发中
  • cocos2d函数

    CCNodeLoader parseProperties CCBReader readNodeGraph kCCBPropTypeBlockCCControl CCInvocation parsePropTypeBlockCCControl
  • 【华为OD机试真题 python】任务最优调度 【2021 H2, 2022 Q1,Q2 考试题】

    题目描述 给定一个正整数组表示待系统执行的任务列表 数组的每一个元素代表一个任务 元素的值表示该任务的类型 请计算执行完所有任务所需的最短时间 任务执行规则如下 任务可以按任意顺序执行 且每个任务执行耗时间均为1个时间单位 两个同类型的任务
  • 双目立体视觉三维重构总结

    文章目录 基本步骤 相机标定 图像采集 立体校正 匹配算法 三维重构 点云去噪 点云显示 总结 前面多多少少记录一些相关知识 由于相关工作还在继续 加上网上的教程总不是十分完善 这里做一个总结 希望自己能够加深对这个过程的整体的理解与认识