结构从运动从两个观点

运动结构(SfM)是从一组二维图像中估计场景的三维结构的过程。这个例子向你展示了如何从两幅图像中估计一个校准过的相机的姿态,重建场景的三维结构到一个未知的比例因子,然后通过检测一个已知大小的物体来恢复实际的比例因子。

概述

这个例子演示了如何用校准过的摄像机从一对二维图像中重建三维场景相机校准器的应用。算法包括以下步骤:

  1. 匹配两个图像之间的稀疏点集。寻找两幅图像之间的点对应有多种方法。此示例使用。检测第一个图像中的角detectMinEigenFeatures函数,并跟踪它们到第二个图像使用vision.PointTracker。你也可以使用extractFeatures紧随其后的是matchFeatures

  2. 使用基本矩阵进行估计estimateFundamentalMatrix

  3. 使用。计算摄像机的运动cameraPose函数。

  4. 匹配两个图像之间的密集点集。重新检测点使用detectMinEigenFeatures以减少“MinQuality”为了得到更多的分数。然后跟踪密集点到第二个图像使用vision.PointTracker

  5. 使用以下命令确定匹配点的三维位置由三角形组成的

  6. 检测一个已知大小的对象。在这个场景中,有一个圆球,其半径为10厘米。使用pcfitsphere在点云里找到地球。

  7. 恢复实际比例尺,得到一个度规重构。

阅读一对图片

将一对图像加载到工作区中。

imageDir = fullfile (toolboxdir (“愿景”),“visiondata”,“upToScaleReconstructionImages”);图像= imageDatastore (imageDir);I1 = readimage(图像,1);I2 = readimage(图像,2);图imshowpair (I1、I2“蒙太奇”);标题(“原始图像”);

负载相机参数

此示例使用由cameraCalibrator参数存储在cameraParams对象,并包括摄像机的内部物理和镜头畸变系数。

%负载预先计算的相机参数负载upToScaleReconstructionCameraParameters.mat

消除镜头畸变

镜头畸变会影响最终重建的精度。可以使用。移除每个图像的失真undistortImage函数。这一过程拉直的线是弯曲的径向失真的镜头。

I1 =不失真时间(I1, cameraParams);I2 =不失真时间(I2, cameraParams);图imshowpair (I1、I2“蒙太奇”);标题(“无畸变的图像”);

查找图像之间的点对应

检测要跟踪的好特性。减少“MinQuality”检测更少的点,这将更均匀地分布在整个图像。如果摄像机的运动不是很大,那么使用KLT算法进行跟踪是一种很好的建立点对应的方法。

%检测特征点imagePoints1 = detectMinEigenFeatures (rgb2gray (I1),“MinQuality”,0.1);%可视化检测点图imshow (I1,“InitialMagnification”,50);标题(“第一张图片中150个最强的角落”);持有情节(selectStrongest (imagePoints1, 150));

创建点跟踪器跟踪= vision.PointTracker(“MaxBidirectionalError”,1“NumPyramidLevels”5);初始化点跟踪器imagePoints1 = imagePoints1.Location;初始化(跟踪、imagePoints1 I1);%跟踪点[imagePoints2, validIdx] = step(tracker, I2);= imagePoints1(validIdx,:);= imagePoints2(validIdx,:);%可视化通讯figure showMatchedFeatures(I1, I2, matchedPoints1, matchedPoints2);标题(“跟踪特性”);

估计基本矩阵

使用estimateFundamentalMatrix函数的作用是:计算基本矩阵,找到满足极限约束的点。

%估计基本矩阵[fMatrix, epipolarInliers] = estimateFundamentalMatrix(matchedPoints1 matchedPoints2,“方法”,“MSAC”,“NumTrials”,10000);%找到极外行星inlierPoints1 = matchedPoints1(偏极化inliers,:);inlierPoints2 = matchedPoints2(偏极化inliers,:);%显示输入匹配figure showMatchedFeatures(I1, I2, inlierPoints1, inlierPoints2);标题(“纵向窗”);

计算相机姿态

计算两幅图像对应的相机姿态之间的旋转和平移。请注意,t是单位向量,因为平移只能按比例计算。

[R, t] = cameraPose(fMatrix, cameraParams, inlierPoints1, inlierPoints2);

重建匹配点的三维位置

重新检测点在第一个图像使用较低“MinQuality”为了得到更多的分数。跟踪新点到第二个图像。方法估计匹配点对应的三维位置由三角形组成的函数,实现了直接线性变换(DLT)算法[1]。将原点置于相机的光学中心,与第一幅图像对应。

%检测稠密特征点imagePoints1 = detectMinEigenFeatures (rgb2gray (I1),“MinQuality”,0.001);创建点跟踪器跟踪= vision.PointTracker(“MaxBidirectionalError”,1“NumPyramidLevels”5);初始化点跟踪器imagePoints1 = imagePoints1.Location;初始化(跟踪、imagePoints1 I1);%跟踪点[imagePoints2, validIdx] = step(tracker, I2);= imagePoints1(validIdx,:);= imagePoints2(validIdx,:);计算相机每个位置的相机矩阵第一个摄像机在原点,沿x轴观察。。因此,其%旋转矩阵为单位矩阵,其平移向量为0。camMatrix1 = cameraMatrix(相机,眼睛(3),[0 0 0]);camMatrix2 = cameraMatrix(cameraParams, R', -t*R');%计算三维点points3D =三角化(matchedPoints1, matchedPoints2, camMatrix1, camMatrix2);%得到每个重建点的颜色numPixels = size(I1, 1) * size(I1, 2);allColors =整形(I1, [numPixels, 3]);colorIdx = sub2ind([size(I1, 1), size(I1, 2)], round(matchedPoints1(:,2)),轮(matchedPoints1 (: 1)));color = allColors(colorIdx,:);创建点云ptCloud = pointCloud (points3D,“颜色”、颜色);

显示三维点云

使用plotCamera的功能,以可视化的位置和方向的相机,和pcshow功能来可视化点云。

想象相机的位置和方向cameraSize = 0.3;图plotCamera (“大小”cameraSize,“颜色”,“r”,“标签”,' 1 ',“不透明度”,0);持有网格plotCamera (“位置”t“定位”R“大小”cameraSize,“颜色”,“b”,“标签”,' 2 ',“不透明度”,0);形象化点云pcshow (ptCloud“VerticalAxis”,“y”,“VerticalAxisDir”,“下来”,“MarkerSize”,45岁);%旋转和缩放的情节camorbit (0, -30);camzoom (1.5);%标记坐标轴包含(“轴”);ylabel (“轴”);zlabel (z轴的)标题(“按比例重建现场”);

把一个球体放到点云上,找到地球仪

通过使用pcfitsphere函数。

%探测地球global = pcfitsphere(ptCloud, 0.1);显示地球的表面情节(全球);标题(“地球的估计位置和大小”);持有

场景的度量重建

地球的实际半径是10厘米。现在可以确定以厘米为单位的三维点的坐标。

确定比例因子scaleFactor = 10 / globe.Radius;缩放点云ptCloud =点云(points3D * scaleFactor,“颜色”、颜色);t = t *比例因子;以厘米为单位想象点云cameraSize = 2;图plotCamera (“大小”cameraSize,“颜色”,“r”,“标签”,' 1 ',“不透明度”,0);持有网格plotCamera (“位置”t“定位”R“大小”cameraSize,“颜色”,“b”,“标签”,' 2 ',“不透明度”,0);形象化点云pcshow (ptCloud“VerticalAxis”,“y”,“VerticalAxisDir”,“下来”,“MarkerSize”,45岁);camorbit (0, -30);camzoom (1.5);%标记坐标轴包含(“轴(cm)”);ylabel (“轴(cm)”);zlabel (“z轴(cm)”)标题(“场景的度量重建”);

摘要

这个例子展示了如何恢复相机的运动和重建一个场景的三维结构从两个图像与校准相机拍摄。

参考文献

[1] Hartley, Richard,和Andrew Zisserman。计算机视觉中的多视图几何。第二版。剑桥,2000年。