1.OpenMVG——(七)初始化
2.一文详解头部位姿估计收藏好文
3.SIFT算法原理与源码分析
OpenMVG——(七)初始化
在上一讲中,源码我们介绍了与Tracks相关的源码概念,构建了帧间的源码数据关联。为了确保运动估计和场景重建的源码稳定性与准确性,一种可靠且高效的源码初始化策略至关重要。开放源代码库OpenMVG提供了两种不同的源码完整授权站源码初始化策略以适应不同场景。
OpenMVG采用了一个基类SfmSceneInitializer来实现这两种策略,源码它们都继承自SfmSceneInitializer,源码这使得C++的源码多态性能够在调用时提供良好的适应性。
首先,源码我们探讨基于两帧初始化的源码策略——SfmSceneInitializerMaxPair。该方案在实现中位于特定路径下,源码其核心在于选取质量最高的源码两帧作为初始化依据。衡量标准是源码特征匹配的数量,通过构建一个按照匹配特征点数量降序排列的源码容器packet_vec,并借助sort_index_helper方法进行排序。
在对排序后的图像对进行遍历时,OpenMVG会逐一验证视图和相机参数的有效性,然后提取所有匹配特征点的坐标,并基于这些数据计算相对运动。具体来说,使用AC-RANSAC方法进行运动模型的估计,这一过程实质上是通过迭代(次)来计算Essential Matrix。在估计运动模型后,OpenMVG使用SVD分解从Essential Matrix中恢复出旋转和平移信息,并通过三角化匹配对和统计内点数量来确定最终的解。
值得注意的是,为了确保模型的可靠性,OpenMVG在选择最终解时添加了一个约束条件,要求最优模型的内点数量至少要比次优的内点数量多一定比例。这一条件与最近邻比例法进行匹配对筛选的原理类似。
在实际应用中,OpenMVG的clang源码国内下载初始化策略不仅仅局限于SfmSceneInitializerMaxPair。为了提供更鲁棒的初始化,还引入了基于星型的初始化方案——SfmSceneInitializerStellar。在实现中,OpenMVG通过查找最佳匹配对来优化初始化过程。与MaxPair方案不同的是,Stellar策略首先将具有相同图像ID的图像对集合到一个map容器中,然后计算所有图像对的平均特征匹配数量,选择平均匹配数量最多的集合作为初始化stellar。
接下来,OpenMVG对选择出的stellar集合中的图像对进行三角化及相对姿态估计,并结合BA优化以得到更精确的相对姿态。在这一阶段,OpenMVG可能遇到一个潜在的代码错误,需要读者在实际应用中进行验证并修正。
这两种初始化策略在OpenMVG中分别通过不同的函数调用实现。在调用过程中,OpenMVG会基于输入参数,如图像对、特征匹配数量等,执行不同的初始化步骤,以适应不同数据集的特性。
从实践角度出发,基于stellar的初始化方法通常展现出更高的鲁棒性,但maxPair方法的初始化难度较低,适合在数据集较为简单或对计算效率有较高要求的情况下使用。读者应根据自己的数据集类型选择合适的初始化方式。
在下一讲中,我们将深入探讨序列SFM(Sequence Structure from Motion)的相关内容,敬请期待!
一文详解头部位姿估计收藏好文
在许多应用中,我们需要知道头部相对于相机是如何倾斜的。例如,心形代码源码在虚拟现实应用程序中,可以使用头部的姿势来渲染场景的正确视图。在驾驶员辅助系统中,汽车上的摄像头可以观察驾驶员的面部,通过头部姿态估计来判断驾驶员是否在关注道路。当然,人们也可以使用基于头部姿势的手势来控制免提应用程序。
本文中我们约定使用下面术语,以免混淆。位姿:英文是pose,包括位置和姿态。位置:英文是location。:英文是photo,本文中用来指一幅照片。图像:英文是image,本文中用在平面或坐标系中,例如image plane指图像平面,image coordinate system指图像坐标系统。旋转:英文是rotation。平移:英文是translation。变换:英文是transform。投影:英文是project。
什么是位姿估计?在计算机视觉中,物体的姿态是指物体相对于相机的相对方向和位置。你可以通过物体相对于相机移动,或者相机相对于物体移动来改变位姿。—— 这二者对于改变位姿是等价的,因为它们之间的关系是相对的。本文中描述的位姿估计问题通常被称为“Perspective-n-Point” 问题,或计算机视觉中的PnP问题。PnP问题的目标是找到一个物体的位姿,我们需要具备两个条件:条件1:有一个已经校准了的波少源码屋相机;条件2:我们知道物体上的n个3D点的位置locations和这些3D点在图像中相应的2D投影。
如何在数学上描述相机的运动?一个3D刚体(rigid object)仅有2种类型的相对于相机的运动。第一种:平移运动(Translation)。平移运动是指相机从当前的位置location其坐标为(X, Y, Z)移动到新的坐标位置(X‘, Y’,Z‘)。平移运动有3个自由度——各沿着X,Y,Z三个轴的方向。平移运动可以用向量t = (X’-X, Y’-Y, Z’-Z)来描述。第二种:旋转运动(Rotation)。是指将相机绕着X,Y,Z轴旋转。旋转运动也有3个自由度。有多种数学上的方法描述旋转运动。使用欧拉角(横摇roll, 纵摇pitch, 偏航yaw)描述,使用3X3的旋转矩阵描述,或者使用旋转方向和角度(directon of rotation and angle)。
进行位姿估计时你需要什么?为了计算一幅图像中一个刚体的3D位姿,你需要下面的信息:信息1:若干个点的2D坐标。你需要一幅图像中若干个点的2D(x, y)位置locations。在人的面部这个例子中,你可以选择:眼角、鼻尖、嘴角等。在本文中,我们选择:鼻尖、下巴、左眼角、右眼角、论文检测软件源码左嘴角、右嘴角等6个点。信息2:与2D坐标点一一对应的3D位置locations。你需要2D特征点的3D位置locations。信息3:相机的内参。正如前文说提到的,在这个PnP问题中,我们假定相机已经被标定了。换句话说,你需要知道相机的焦距focal length、图像的光学中心、径向畸变参数。
位姿估计算法是如何工作的?有很多的位姿估计算法,最有名的可以追溯到年。该算法的详细讨论超出了本文的讨论范围。这里只给出其简要的核心思想。该位姿估计PnP问题涉及到3个坐标系统。(1)世界坐标系。前面给出的各个面部特征的3D点就是在世界坐标系之中;(2)如果我们知道了旋转矩阵R和平移向量t,我们就能将世界坐标系下的3D点“变换Transform”到相机坐标系中的3D点。(3)使用相机内参矩阵,能将相机坐标系中的3D点能被投影到图像平面image plane, 也就算图像坐标系统image coordinate system。整个问题就是在3个坐标系统中玩耍:3D的世界坐标系World coordiantes、3D的相机坐标系Camera coordinates、2D的图像坐标系Image coordinates。下面,我们来深入研究图像生成方程式,以理解上述三个坐标系是如何工作的。
在上述中,左下角的O是相机的中心,中间的平面Image Plane就是像平面,我们感兴趣的是找出“将3D点P投影到像平面中点p的方程式”。首先,我们假设已经知道了位于世界坐标系中3D点P的位置(U,V,W),如果我们还知道了世界坐标系相对于相机坐标系之间的旋转矩阵R和平移向量t,通过下面方程式,就能计算出点P在相机坐标系下的位置(X,Y,Z)。
下面,我们来深入研究图像生成方程式,以理解上述三个坐标系是如何工作的。在上述中,左下角的O是相机的中心,中间的平面Image Plane就是像平面,我们感兴趣的是找出“将3D点P投影到像平面中点p的方程式”。首先,我们假设已经知道了位于世界坐标系中3D点P的位置(U,V,W),如果我们还知道了世界坐标系相对于相机坐标系之间的旋转矩阵R和平移向量t,通过下面方程式,就能计算出点P在相机坐标系下的位置(X,Y,Z)。
正如将在下面章节讲述的,我们知道(X, Y, Z)只在一个未知的尺度上或者说(X, Y, Z)仅由一个未知的尺度所决定,所以我们没有一个简单的线性系统。
直接线性变换(Direct Linear Transform)我们已经知道了3D模型世界坐标系中的很多点也就是(U,V,W),但是,我们不知道(X, Y, Z)。我们只知道这些3D点对应的2D点在图像平面Image Plane中的位置也就是(x, y)。在不考虑畸变参数的情况下,像平面中点p的坐标(x,y)由下面的方程式(3)给出。方程式(3)中的s是什么?它是一个未知的尺度因子scale factor。由于在图像中我们没有点的depth信息,所以这个s必须存在于方程中。引入s是为了表示:图2中射线O-P上的任何一点,无论远近,在像平面Image Plane上的都是同一个点p。也就是说:如果我们将世界坐标系中的任何一点P与相机坐标系的中心点O连接起来,射线O-P与像平面Image Plane的交点就是点P在像平面上的像点p,该射线上的任何一点P,都将在像平面上产生同一个像点p。现在,上面这些讨论已经将方程式(2)搞复杂了。因为这已经不是我们所熟悉的、能解决的一个“好的线性方程”了。我们方程看起来更像下面的形式。不过,幸运的是,上面形式的方程,可以使用一些“代数魔法”来解决——直接线性变换(DLT)。当你发现一个问题的方程式“几乎是线性的,但又由于存在未知的尺度因子,造成该方程不完全线性”,那么你就可以使用DLT方法来求解。
列文伯格-马夸尔特优化算法(Levenberg-Marquardt Optimization)由于下面的一些原因,前面阐述的DLT解决方案并不能非常精确地求解。第一:旋转向量R有3个自由度,但是DLT方案中使用的矩阵描述有9个数,DLT方案中没有任何措施“强迫估计后得到的3X3的矩阵变为一个旋转矩阵”。更重要的是:DLT方案没有“正确的目标函数”。的确,我们希望能最小化“重投影误差reprojection error”,正如下面将要讲的。
对于方程式(2)和方程式(3),如果我们知道正确的位姿(矩阵R和向量t),通过将3D点投影到2D像平面中,我们能预测到3D面部点的2D点在图像中的位置locations。换而言之,如果我们知道R和t,对于每一个3D点P,我们都能在像平面上找到对于的点p。我们也知道了2D面部特征点通过Dlib或者手工点击给出。我们可以观察被投影的3D点和2D面部特征之间的距离。当位姿估计结果是准确的时候,被投影到像平面Image Plane中的3D点将与2D面部特征点几乎完美地对齐。但是,当位姿估计不准确时,我们可以计算“重投影误差reprojection error”——被投影的3D点和2D面部特征点之间的距离平方和。
位姿(R和t)的近似估计可以使用DLT方案。改进DLT解决方案的一个简单方法是随机“轻微”改变姿态(R和t),并检查重投影误差是否减小。如果的确减小了,我们就采用新的估计结果。我们可以不断地扰动R和t来找到更好的估计。尽管这种方法可以工作,但是很慢。可以证明,有一些基本性的方法可以通过迭代地改变R和t的值,从而降低重投影误差。——其中之一就是所谓的“列文伯格-马夸尔特优化算法”。在OpenCV中,有两种用于位姿估计的API:solvePnP和solvePnPRansac。solvePnP实现了几种姿态估计算法,可以使用参数进行选择不同的算法。默认情况下,它使用标志SOLVEPNP_ITERATIVE,其本质上是DLT解决方案,然后是列文伯格-马夸尔特算法进行优化。SOLVEPNP_P3P只使用3个点来计算姿势,并且应该只在使用solvePnPRansac时使用。在OpenCV3中,引入了SOLVEPNP_DLS和SOLVEPNP_UPNP两种新方法。关于SOLVEPNP_UPNP有趣的事情是,它在估计位姿时,也试图估计相机内部参数。solvePnPRansac中的“Ransac”是“随机抽样一致性算法Random Sample Consensus”的意思。引入Ransac是为了位姿估计的鲁棒性。当你怀疑一些数据点是噪声数据的时候,使用RANSAC是有用的。
样例CMakeLists.txt文件:文件:源代码:OAK中国|追踪AI技术和产品新动态公众号|OAK视觉人工智能开发点「这里」添加微信好友(备注来意)戳「+关注」获取最新资讯↗↗
SIFT算法原理与源码分析
SIFT算法的精密解析:关键步骤与核心原理
1. 准备阶段:特征提取与描述符生成 在SIFT算法中,首先对box.png和box_in_scene.png两张图像进行关键点检测。利用Python的pysift库,通过一系列精细步骤,我们从灰度图像中提取出关键点,并生成稳定的描述符,以确保在不同尺度和角度下依然具有较高的匹配性。 2. 高斯金字塔构建计算基础图像的高斯模糊,sigma值选择1.6,先放大2倍,确保模糊程度适中。
通过连续应用高斯滤波,构建高斯金字塔,每层图像由模糊和下采样组合而成,每组octave包含5张图像,从底层开始,逐渐减小尺度。
3. 极值点检测与极值点定位在高斯差分金字塔中寻找潜在的兴趣点,利用邻域定义,选择尺度空间中的极值点,这些点具有旋转不变性和稳定性。
使用quadratic fit细化极值点位置,确保匹配点的精度。
4. 特征描述与方向计算从细化的位置计算关键点方向,通过梯度方向和大小统计直方图,确定主次方向,以增强描述符的旋转不变性。
通过描述符生成过程,旋转图像以匹配关键点梯度与x轴,划分x格子并加权叠加,生成维的SIFT特征描述符。
5. 精度校验与匹配处理利用FLANN进行k近邻搜索,执行Lowe's ratio test筛选匹配点,确保足够的匹配数。
执行RANSAC方法估计模板与场景之间的homography,实现3D视角变化适应。
在场景图像上标注检测到的模板并标识SIFT匹配点。
SIFT的独特性:它提供了尺度不变、角度不变以及在一定程度上抵抗3D视角变化的特征,是计算机视觉领域中重要的特征检测和描述算法。