草庐IT

线结构光三维重建(一)

beyond951 2023-05-18 原文

        线结构光三维重建测量系统,是基于三角测量的原理进行三维重建。相机在采集图像过程中,对相机进行内外参标定后,我们可以将图像上的像素点坐标,转为世界坐标进行测量。但由于小孔成像的原理,对于目标距离光心的深度信息无法进行测量。为获得目标的深度信息,引入线激光系统,线激光投射下来,为一个光平面;光平面的约束使得目标物体的深度信息可以求解。

        该系列文章涉及到线激光三维重建的原理、光平面标定、激光轮廓提取、相机标定和三维重构。本篇以阐述线结构光三维重建的原理、光平面的标定方法、激光轮廓提取的方法为主。后续将进一步实现光平面多种不同方法的标定、相机标定和激光轮廓的提取。

线结构光三维重建测量原理

        整个成像系统示意图如下图所示。我们可以看到主要分为两个子系统,即激光发生器构成的激光系统和相机构成的成像系统。首先我们假定所有点的关系基于相机坐标系,即坐标系原点为光心所在的位置Oc,成像系统基于相机标定模型,相机标定完成后得到相机内参,基于相机内参可以得到目标物体P点在成像面P'点的位置坐标(Xc,Yc,Zc)。具体推导求解过程参考博文北邮鲁鹏老师三维重建课程之相机标定https://blog.csdn.net/beyond951/article/details/122201757?spm=1001.2014.3001.5501当P'点的位置坐标(Xc,Yc,Zc)已知后,Oc坐标为(0,0,0),因此空间直线OcP'直线方程可以得到。

        空间直线方程得到后,联立激光发生器投射的光平面方程。直线与平面的交点P(Xw,Yw,Zw)即可通过求解得到。但这一步求得坐标为相机坐标系下的坐标。将该点的坐标乘以相机标定过程中得到的相机外参即可得到该点世界坐标。

        综上所述,线结构光三维重建成像系统,在于引入激光发生器投射的光平面约束,使得目标距离相机光心的深度信息可解。

         线结构光实现三维重建的整体技术路线如下图所示 。其中技术要点在于光平面标定、激光轮廓提取和相机标定。其中相机标定在这里不再赘述。

        其整个过程的详细实现路线图如下图所示

光平面标定方法

        参考文章来源:Line structured light calibration method and centerline extraction- A review 2020

        该小节论述了线结构光光平面标定的关键技术。对矢量叉乘、线性方程解、交叉比不变性、消失点与线等主要标定方法进行了分析。下面分开对上述提到光平面方法进行论述。

矢量叉乘

        对于线结构光系统,标定相机坐标系中光平面的方程参数至关重要,光平面的法向量可以由两个不平行的激光条纹向量的叉乘得到。其示意图如下图所示。

其中当向量M1M2和向量M1'M2'可知时,两个向量的叉乘即为光平面的法向量;同时两个已知向量的点乘即为向量的交点。已知平面上一点和平面的法向量即平面方程可得。

线性方程组解法

        通过建立相机像素与世界参考点之间的线性关系来求解线性方程。其关系是

 其中s为比例因子,ri(i = 1,2)为旋转矩阵第i列的列向量。在摄像机坐标系中,通过求解旋转矩阵和平移向量可以得到平面方程。

 因此,至少需要4组已知的目标参考点和像素点来求解相机坐标系与世界坐标系之间的变换矩阵。在求解线性方程的方法中,重点是通过变换矩阵得到世界坐标系和摄像机坐标系中参考点的对应关系。然后,对变换矩阵进行转换,计算出光平面方程。

交比不变性

        交叉比不变性方法是立体视觉的基本理论,在线结构系统中得到了广泛的应用。成像系统如下图所示。

 根据交比不变性的性质,关系可以表示为:

        其中AB、AC、BQ、QC分别为世界坐标系中的欧氏距离,ab、qb、ac、qc分别为像素坐标系中对应坐标点的像素距离。这样就可以计算出激光线与目标的交点Q,从而确定光的平面方程。

消失点、线方法

       消失点和消失线也是立体视觉中的理论,其原理如下图所示。透视投影后,空间中的平行线在相机坐标中不再平行。理想情况下,空间中的平行线相交于摄像机坐标中的一点,这一点被定义为平行线的消失点。如下图所示,点v1和点v2分别为目标在垂直方向和水平方向平行线的归零点。两点的直线l构成位置下目标平面的消失线。需要注意的是,目标的放置要避免目标面和摄像机的像面平行的情况。否则,它们之间的映射关系将变成仿射变换。如果仿射变换是平行的,那么平行线的像也是平行的,不会相交于一点。

影消点与影消线计算相机内参和平面法向量过程参考如下:

单视图重构—影消点、影消线与相机内参、平面法向量的推导https://blog.csdn.net/beyond951/article/details/125791301?spm=1001.2014.3001.5501

激光轮廓提取

        参考文章来源:激光双目三维成像关键技术研究

        在线结构光系统中,大多数标定方法都需要得到激光条纹与目标的交点。因此,激光中心线的提取具有极其重要的意义。研究人员提出了多种提取激光条纹中心线的算法。中心线提取可分为灰度质心法、Steger算法。

灰度重心法

        灰度重心法可以看成以灰度平方为加权值的加权计算激光轮廓中心的方法,其精度可以达到亚像素精度,精度高于骨架提取方法。该方法沿着光条横截面的方向进行扫描,筛选出灰度值最大点以及灰度值大于极大值与阈值的差值的所有像素点,然后对于这些像素点,灰度值视为该像素点的权重,对该行筛选出的这些点坐标进行加权平均,得到的坐标值就被视作光条中心。激光光条灰度分布图像如下图所示:

        设事先设置的灰度阈值为 T,沿着光条横截面方向进行搜索,首先找到该行中灰度值最大的像素点位置 C,其灰度值为 Gmax,接着从该最大灰度值点处向光条两边搜索,找出高于自适应阈值线 Gmax− T 的所有像素点,不妨设满足高于阈值的两个边界点分别为 A,B,两边界点之间的 n 个像素点中的第 i 个像素点列坐标值为 yi,对应的灰度值为 gi,那么利用重心计算公式可以得到该行的光条中心位置的列坐标 Y:

 逐行或者逐列进行上述运算,即可提取出完整的激光轮廓的中心。

Steger算法

        德国慕尼黑大学的 Steger 教授首次提出了一种基于 Hessian 矩阵的亚像素级别精度的光条中心提取算法。Steger 教授首次在其论文中提出了一种名为 Hessian矩阵的概念,该矩阵是通过求取事先设置好的高斯卷积模板对图像两方向的二阶导数和相应图像区域像素点的卷积来得到。具体来说,在激光光条的图像中,Hessian 矩阵的表达式如下:

        该矩阵由图像某点沿不同方向的四个偏导组成,该矩阵可以确定z(x,y)的二阶方向导数最大绝对值的方向。接下来的思路就是:首先进行高斯滤波,然后计算Hessian矩阵得到光条的法线方向,最后在法线方向利用泰勒展开得到亚像素位置。详细原理说明过程此处不再赘述。

总结

        本篇博文阐述了线激光三维重建成像系统的原理、系统标定和激光轮廓条纹中心提取的方法。其中重难点在于系统的标定(相机标定和光平面方程的标定)和激光轮廓高精度提取,二者精度决定了整个系统的测量精度。后续将针对上面提到的整个过程进行代码实现。

有关线结构光三维重建(一)的更多相关文章

  1. 视频融合技术解决方案,三维全景拼接赋能平台 - 2

    近年来,随着信息化时代的到来,三维全景拼接以视频监控领域为代表的智能硬件公司迅速崛起,随后全国各地在视频监控领域进行了大量的建设。但随着摄像头数量的增加,视频监控画面离散、庞杂、关联性差等诸多问题日渐凸显。如何优化现有视频技术,助力管理者或使用者有效、直观、准确地掌控现场实时动态,成为我国信息化前行路上面临的新课题。视频融合技术平台解决方案北京智汇云舟科技有限公司成立于2012年,专注于创新性的“视频孪生(实时实景数字孪生)”技术研发与应用。公司依托自研三维地理信息引擎(3DGIS),融合建筑信息模型(BIM)、视频监控(Video)、人工智能(AI)及物联网(IOT)等多种技术,并在此基础上

  2. ruby - 如何为所有已安装的 gem 重建 rdoc? - 2

    我在多个位置安装了多个gem。生成/重新生成的困难/简单方法是什么:所有这些已安装的gem的rdoc,一次全部?所有这些已安装的gem的yardoc,一次全部? 最佳答案 你试过其中之一吗?gemrdoc--allgemrdoc--all--overwrite 关于ruby-如何为所有已安装的gem重建rdoc?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/3152857/

  3. javascript - 重建以 JSON 序列化的对象 - 2

    在我的网络应用程序中,我使用JSON.stringify()asdescribedhere序列化存储对象.这太棒了,我可以轻松地从JSON字符串重新创建对象,但我丢失了所有对象的方法。有没有一种简单的方法可以将这些方法添加回我忽略的对象-可能涉及原型(prototype)制作,这是我不太熟悉的东西?或者这只是我自己创建一个复杂的函数来执行此操作的情况?编辑:理想情况下,我正在寻找类似的东西:Object.inheritMethods(AnotherObject); 最佳答案 调用JSON.parse后获得对象后,您有很多选择。这里有

  4. DJI Pilot无人机航线规划-实景三维建模全流程 - 2

    目前很多网上推荐的无人机航线规划软件如Altizure、航测通等难以下载或为商用软件。该文章以大疆精灵4为例演示DJIPilot航线规划-CC实景建模-三维模型导入Cesiumlab3全流程。目录一、软件准备二、DJIPilot航线规划1、准备工作1.1了解测区环境1.2检查无人机2、航线规划2.1创建测绘区域2.2参数设置3、执行飞行任务三、CC实景建模1.1创建工程1.2添加影像1.3影像设置1.4提交空中三角测量1.5空间框架参数设置四、在cesiumlab3上导入三维模型2.1OSGB格式转为3Dtiles2.2导入3D模型附录:1、GSD2.不同区域像控点选取:3、奥维地图在测绘作业

  5. 三维点云| CloudCompare软件使用总结 - 2

    一、Fileopen:打开文件save:保存应用实例:CloudCompare——laz与las格式点云相互转换及代码实现https://blog.csdn.net/qq_36686437/article/details/119945199GlobalShiftsettings:设置最大绝对坐标,最大实体对角线PrimitiveFactory:生成三维几何体模型应用实例:CloudCompare——生成常见几何点云https://blog.csdn.net/qq_36686437/article/details/1200091303Dmouse:对3D鼠标(如3Dconnexion)的支持Cl

  6. go - gorilla cookie session 会持续服务器重建吗? - 2

    我正在使用以下代码在我的包中传递当前session。我正在用fresh构建它来监视我的文件。似乎在构建cookie后不再有效?我已经尝试过cookie存储和mysql存储。我已确认cookie仍在浏览器中,行项目仍在数据库中。varsessionStore=sessions.NewCookieStore([]byte(os.Getenv("SESSION_SECRET")))varsessionPointer*sessions.Session;funcinitSession(r*http.Request)*sessions.Session{ifsessionPointer==nil{}

  7. 深度学习三维图像数据增强——Monai实现 - 2

    深度学习三维图像数据增强——Monai实现一、前言二、数据类型三、Compose四、OneOf五、常见转换类型5.1裁减和填充5.2强度增强5.3空间增强六、注意(记录坑)6.1RandRotate90一、前言笔者接触深度学习不久,跑过一些二维图像的深度学习代码,对于二维图像,深度学习数据增强可借助skimage、opencv、imgaug、Albumentations、Augmentor等多数主流的库实现,在这里放一个大神的链接,可供参考。但对于三维数据,能够借助的库便少了起来,常用的有TorchIO和Monai,而针对于医学领域,Monai是一个不错的选择。笔者通过自学,将Monia库总结

  8. go - 在 docker 上更改文件时重建 - 2

    我开始使用docker(在MacOSX上使用boot2docker)和golang,每当我对我的.go文件进行更改时,我希望在docker图像上可见。有没有办法做到这一点?或者docker不适合做这件事?谢谢 最佳答案 默认情况下,Docker不会这样做。我在我的问答中描述了几种方法here.一个简单的方法来完成你想要的是使用观察者(如nodemon)来监视你的文件夹并启动一个脚本(或者更好,使用fig)来重新创建和运行你的图像。 关于go-在docker上更改文件时重建,我们在Stac

  9. 使用正则表达式的 Python XML 重建 - 2

    我有这个部分XMLstring='''someValuesomeValue'''现在我想“傻傻地”修复一下。我想到了一种方法-对所有开始元素和结束元素进行正则表达式-->检查缺少哪个元素并添加它。当然,不要涉及太多细节。到目前为止我得到的是(这不起作用):importrestarts=re.compile('(?)|(?)')print(start.findall(string))我期望的是x:root、x:tag2、x:tag3的列表我一直在谷歌上搜索并尝试了很多,但找不到答案。我从这个表达式中得到的唯一东西是x:root、x:tag1、x:tag3。请帮忙谢谢

  10. c# - 将 XML 结构重建为递归样式列表/XMLReader 替代方案 - 2

    问题:我一直在尝试解析xml,并为XML中的每个节点创建一个对象。问题:由于我的xml具有任意顺序的节点,并且有些节点是其他节点的子节点,因此我很难在不使用.net1.1和XmlNode类的情况下从逻辑上解析它们。注意:我希望只使用XMLReader,因为我仅限于.NetStandard1.0,并且不想安装任何额外的库。(参见此处:https://learn.microsoft.com/en-us/dotnet/standard/net-standard)目前我为每个xml节点创建一个对象,每个对象包含一个我希望添加到的子组件列表,如果它找到一个子节点。但是我似乎无法递归搜索xml并将

随机推荐