(结构光)单目+结构光三维重构总体结构

博主是那种动手能力较差的人(超级容易踩坑,一个坑踩超级久),独自搭建一个单目+结构光系统是真的挺挑战的。
在自己做的过程中,最让人心累的就是,我结果不好的话,会认为是投影仪不够好才标定出问题的bulabulabula…,基本上卡着我的点都是诸如“怎么从投影仪投射一张正常的图片”这种让大佬们感觉很低级的问题。其实我的确很容易被所谓“低级问题”卡住,这也是需要进步的一个点。
本次实验主要参考了这位博主的3D重构系列博客。

相机+投影仪

相机是从包工头那里拿的MindVision,投影仪是博主还是白的时候从京东买的一个200多的“家庭影院”投影仪,物理分辨率800*480。听说别人用的都是几千块的投影仪,我的200块,我……是有点怕的。

系统标定

包括两个部分,相机标定和投影仪标定。OpenCV和MATLAB都有对应的标定工具,由于我使用的C++,所以用的OpenCV标定。标定过相机的伙伴可能对相机标定已经不陌生了,那么系统标定主要是投影仪怎么标定了。
OpenCV标定将投影仪看做一个相机模型,使用棋盘格进行标定。且只要知道了投影仪图片的角点坐标+角点坐标对应的世界坐标就能够对投影仪进行标定了。
具体操作坚持一个原则:保证打印棋盘格(用于相机的标定)和投影棋盘格在同一个平面上(对我来说比较难的是采集图片,我苦于没有准备好白板,标定的事情拖了好久好久)。采集图片时,保持相机与投影仪的相对位姿不变,改变白板与相机+投影仪系统的相对位姿,使用相机采集图片。
新手疑问1:打印棋盘格和投影棋盘格怎么摆?如图,相互不交叉,且角点个数不一样就可以了,保证角点个数不一样是为了在运行程序的时候区分是打印的其棋盘格还是投影的棋盘格(也就是标定的是相机还是投影仪)
(结构光)单目+结构光三维重构总体结构_第1张图片
新手疑问2:投影仪世界坐标和图片坐标怎么得到?系统首先标定相机,标定相机之后,提取上图中投影棋盘格的角点并计算这些角点的世界坐标(投影仪的世界坐标get);投影用的那张图片相当于投影仪相机模型中“相机采集到的图片”,提取角点就得到了标定中需要的图片角点坐标。然后就可以标定了。
新手疑问3:如何确定相机和投影仪的位姿?我看的以篇论文中提到,标定时得到相机RT,投影仪RT每一组都能够用作重构,对应的只是选择了不同的世界坐标系而已。对于重构结果没有本质上的影响。
新手疑问4:如果不小心动了投影仪和相机怎么办?动了就摆回去喽。。。摆不回去的话,内参无需重新标定,只需要重新标定外参就可以了。新手可以参考OpenCV中的函数solvePnPRansac(),这个函数就是知道了角点的世界坐标和图片坐标和相机内参和畸变系数能够得到相机相对于世界坐标系的RT的函数。这个函数真是太妙了。
我在标定这里踩了比较多的坑,最最最大的坑就是,我不知道使用多大的图片合适。可能第一次标定用的投影图片得到的结果也能用吧,但是我的测试结果不太好。最好就是采用与自己的投影仪物理分辨率一致的图片

三维重构原理

单目+结构光系统的原理与双目原理一样,只要找到了两张图片之间的像素对应关系+标定结果就能三角测量了。唯一的不同点就是寻找对应像素的方式不同。双目系统直接运行对应的算法就可以了,例如OpenCV中的SGBM算法。单目+结构光妙在结构光,通过对结构光进行编码、解码,得到像素之间的对应关系。我的投影仪正弦性不是很好,所以,我用的格雷码,这也是我参考开头那位博主的方法的原因。
在系统已经标定好的前提下,通过相机采集一批图片,然后对图片进行二值化,得到每个图片每个像素的格雷码,对格雷码解码之后得到的就是像素在“投影仪采集的(投影图片)图片中的位置”,如此一来,我们就得到了两张图片之间的像素对应关系,加上前边的标定结果,直接对“对应像素”进行三角测量就可以了。

我是不是写的太大白话了。。。

测试重构一个白色的方块
在这里插入图片描述
通过MATLAB中表示的结果,能够发现,点云分层,方块的上表面与白板分开。说明总体原理实现是正确的。
(结构光)单目+结构光三维重构总体结构_第2张图片
下一步应该是对点云中的离群点进行剔除。

你可能感兴趣的:(3D)