运动结构(SfM)是从一组二维图像中估计场景的三维结构的过程。这个例子向您展示了如何从两幅图像中估计校准相机的姿态,重建场景的三维结构到一个未知的比例因子,然后通过检测一个已知大小的对象恢复实际的比例因子。
这个例子展示了如何从一对2d图像中重建一个3d场景摄像机校准器该算法包括以下步骤:
匹配两幅图像之间的稀疏点集。有多种方法可以找到两个图像之间的点对应关系。这个例子在第一张图像中使用检测微小特征
函数,并跟踪它们到第二个图像使用愿景。PointTracker
. 或者,您可以使用extractFeatures
紧随其后的是matchFeatures
.
估计基本矩阵使用estimateEssentialMatrix
.
计算相机的运动使用relativeCameraPose
函数。
在两幅图像之间匹配密集的点集。重新检测使用的点检测微小特征
以减少“MinQuality”
获取更多点。然后使用愿景。PointTracker
.
使用。确定匹配点的三维位置由三角形组成的
.
检测一个已知大小的对象。在这个场景中,有一个半径为10厘米的球体。使用pcfitsphere
在点云里找到地球仪。
恢复实际比例,生成公制重建。
将一对图像加载到工作区中。
imageDir = fullfile (toolboxdir (“愿景”),“视觉数据”,“upToScaleReconstructionImages”);图像= imageDatastore (imageDir);I1 = readimage(images, 1);I2 = readimage(images, 2);图imshowpair (I1、I2“蒙太奇”);标题(原始图像的);
这个例子使用的相机参数计算摄像机校准器应用。参数存储在cameraParams
对象,并包括摄像机固有特性和镜头失真系数。
加载预先计算的摄像机参数负载超大规模施工摄像机参数表
透镜畸变会影响最终重建的精度。您可以删除失真从每个图像使用不失真图像
函数。这一过程使因透镜的径向畸变而弯曲的线变直。
I1 = undistortion timage (I1, cameraParams);I2 = undistortion timage (I2, cameraParams);图imshowpair (I1、I2“蒙太奇”);标题(“无畸变的图像”);
检测好的特征来跟踪。减少“MinQuality”
如果摄像机的运动不是很大,那么使用KLT算法进行跟踪是建立点对应关系的好方法。
检测特征点imagePoints1 = detectMinEigenFeatures (im2gray (I1),“MinQuality”, 0.1);%可视化检测到的点图imshow(I1,“初始放大”, 50);标题(“第一张图像的150个最强角”);持有在情节(selectStrongest (imagePoints1, 150));
%创建点跟踪器追踪=愿景。PointTracker (“MaxBidirectionalError”1.“NumPyramidLevels”, 5);初始化点跟踪器imagePoints1=imagePoints1.位置;初始化(跟踪器,imagePoints1,I1);%追踪要点[imagePoints2,validix]=步骤(跟踪器,I2);匹配点s1=imagePoints1(validix,:);匹配点s2=imagePoints2(validix,:);%可视化通信图showMatchedFeatures(I1, I2, matchedPoints1, matchedPoints2);标题(“跟踪功能”);
使用estimateEssentialMatrix
函数计算基本矩阵并找到满足极线约束的内点。
估算基本矩阵[E,外极线]=估计基本矩阵(...匹配点1,匹配点2,摄像机参数,“信心”, 99.99);%寻找极线入口inlierPoints1 = matchedPoints1(epipolarInliers,:);inlierPoints2 = matchedPoints2(epipolarInliers,:);%显示嵌套匹配图中显示了匹配的特征(I1、I2、inlierPoints1、inlierPoints2);头衔(“极线内线”);
计算第二摄像机相对于第一摄像机的位置和方向。请注意,T
是平移单位向量,因为平移只能按比例计算。
[orient,loc]=相对坐标(E,摄像机参数,内点1,内点2);
在第一个图像中使用较低的点重新检测“MinQuality”
要获取更多点,请在第二张图像中跟踪新点。使用由三角形组成的
函数,该函数实现直接线性变换(DLT)算法[1]。将原点放置在与第一幅图像对应的相机光学中心。
%检测密集特征点。使用ROI排除靠近目标的点%的图像边缘。roi = [30,30, size(I1, 2) - 30, size(I1, 1) - 30];imagePoints1 = detectMinEigenFeatures (im2gray (I1),“投资回报”投资回报率...“MinQuality”, 0.001);%创建点跟踪器追踪=愿景。PointTracker (“MaxBidirectionalError”1.“NumPyramidLevels”, 5);初始化点跟踪器imagePoints1=imagePoints1.位置;初始化(跟踪器,imagePoints1,I1);%追踪要点[imagePoints2,validix]=步骤(跟踪器,I2);匹配点s1=imagePoints1(validix,:);匹配点s2=imagePoints2(validix,:);%计算相机的每个位置的相机矩阵%第一个摄像机在原点沿z轴观察。因此,其变换是恒等式。tform1 = rigid3d;camMatrix1 = cameraMatrix(cameraParams, tform1);%计算第二个摄像机的外部cameraPose = rigid3d(orient, loc);tform2 = cameraPoseToExtrinsics (cameraPose);camMatrix2 = cameraMatrix(cameraParams, tform2);%计算三维点点3d=三角化(匹配点s1、匹配点s2、cammarix1、cammarix2);%获取每个重建点的颜色numPixels=大小(I1,1)*大小(I1,2);所有颜色=重塑(I1,[numPixels,3]);colorIdx=sub2ind([size(I1,1),size(I1,2)],圆形(匹配点1(:,2)),...圆形(匹配点1(:,1));颜色=所有颜色(colorIdx,:);%创建点云ptCloud=点云(点3d,“颜色”、颜色);
使用绘图仪
用于可视化摄像机的位置和方向,以及pcshow
函数以可视化点云。
%可视化摄像机的位置和方向cameraSize = 0.3;图plotCamera (“大小”cameraSize,“颜色”,“r”,“标签”,'1',“不透明度”,0);保持在网格在plotCamera (“位置”疯狂的,“定位”朝向“大小”cameraSize,...“颜色”,“b”,“标签”,'2',“不透明度”, 0);%可视化点云pcshow (ptCloud“VerticalAxis”,“y”,“VerticalAxisDir”,“下来”,...“MarkerSize”, 45岁);%旋转并缩放绘图camorbit (0, -30);camzoom (1.5);%标记轴包含(“x轴”);伊莱贝尔(“y轴”);zlabel (“z轴”)标题(“场景的高比例重建”);
通过使用pcfitsphere
函数。
%探测地球globe=pcfitsphere(ptCloud,0.1);显示地球的表面情节(全球);标题(“地球的估计位置和大小”);持有从
地球的实际半径是10厘米。你现在可以确定三维点的坐标,单位是厘米。
%确定比例因子比例因子=10/地球半径;%缩放点云ptCloud=pointCloud(points3D*scaleFactor,“颜色”、颜色);loc = loc * scaleFactor;%以厘米为单位可视化点云cameraSize = 2;图plotCamera (“大小”cameraSize,“颜色”,“r”,“标签”,'1',“不透明度”,0);保持在网格在plotCamera (“位置”疯狂的,“定位”朝向“大小”cameraSize,...“颜色”,“b”,“标签”,'2',“不透明度”, 0);%可视化点云pcshow (ptCloud“VerticalAxis”,“y”,“VerticalAxisDir”,“下来”,...“MarkerSize”, 45岁);camorbit (0, -30);camzoom (1.5);%标记轴包含(“轴(cm)”);伊莱贝尔(“轴(cm)”);zlabel (‘z轴(厘米)’)标题(“场景的度量重建”);
这个例子展示了如何恢复相机的运动和重建一个场景的3-D结构从两个图像与校准相机。
[1] Hartley,Richard和Andrew Zisserman.计算机视觉中的多视图几何.第二版.剑桥,2000。