主要内容

从两种视角看运动的结构

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

概述

该示例演示如何从相机拍摄的一对二维图像重建三维场景相机校准器该算法由以下步骤组成:

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

  2. 估计基本矩阵使用estimateEssentialMatrix

  3. 计算相机的运动使用estrelpose函数。

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

  5. 确定匹配点的三维位置由三角形组成的

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

  7. 恢复实际比例尺,生成度量重构。

读一组图片

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

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

图中包含一个axes对象。标题为Original Images的axes对象包含一个image类型的对象。

负载相机参数

这个例子使用了计算的摄像机参数相机校准器参数存储在cameraIntrinsics对象,并包含相机的本征系数和镜头失真系数。

装载预先计算的相机intrinsicdata =负载(“sfmCameraIntrinsics.mat”);intrinsic = data.intrinsics;

消除镜头畸变

透镜畸变会影响最终重建的精度。方法可以从每张图像中删除失真undistortImage函数。这一过程使由于透镜的径向畸变而弯曲的线条变直。

I1 = undistortion timage (I1, intrinsic);I2 = undistortion timage (I2, intrinsic);图imshowpair (I1、I2“蒙太奇”);标题(“无畸变的图像”);

图中包含一个axes对象。标题为undistortion Images的axes对象包含一个类型为image的对象。

找到图像之间的点对应关系

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

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

图中包含一个axes对象。标题为150的axes对象包含两个类型为Image, line的对象。

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

估计基本矩阵

使用estimateEssentialMatrix函数计算基本矩阵,并找出满足极线约束的内层点。

估计基本矩阵[E, epipolarInliers] = estimateEssentialMatrix(...matchedPoints1, matchedPoints2, intrinsic, Confidence = 99.99);找到极内嵌物inlierPoints1 = matchedPoints1(epipolarInliers,:);inlierPoints2 = matchedPoints2(epipolarInliers,:);%显示内部匹配图showMatchedFeatures(I1, I2, inlierPoints1, inlierPoints2);标题(“纵向窗”);

计算相机姿势

计算第二个相机相对于第一个相机的位置和方向。请注意,疯狂的是一个翻译单位向量,因为翻译只能按比例计算。

relPose = estrelpose(E, intrinsic, inlierPoints1, inlierPoints2);

重建匹配点的三维位置

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

检测密集特征点。使用ROI来排除接近的点%的图像边缘。边境= 30;roi = [border, border, size(I1, 2)- 2*border, size(I1, 1)- 2*border];imagePoints1 = detectMinEigenFeatures(im2gray(I1), ROI = ROI,...MinQuality = 0.001);创建点跟踪器追踪=愿景。PointTracker(MaxBidirectionalError=1, NumPyramidLevels=5);初始化点跟踪器imagePoints1 = imagePoints1.Location;初始化(跟踪、imagePoints1 I1);%跟踪分数[imagePoints2, validIdx] = step(跟踪器,I2);matchedPoints1 = imagePoints1(validIdx,:);matchedPoints2 = imagePoints2(validIdx,:);为相机的每个位置计算相机矩阵。第一个摄像机在原点沿着z轴看。。因此,其变换就是恒等式。camMatrix1 = cameraProjection(intrinsic, rigidtform3d);camMatrix2 = cameraProjection(intrinsic, pose2extr(relPose));计算三维点points3D = triangulate(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,“颜色”、颜色);

显示3d点云

使用plotCamera函数来可视化相机的位置和方向pcshow函数可视化点云。

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

在点云上安装一个球体,找到球体

方法将球体与3-D点拟合,从而在点云中找到球体pcfitsphere函数。

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

场景的度量重建

球体的实际半径是10厘米。你现在可以确定3-D点的坐标,单位是厘米。

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

总结

这个例子展示了如何恢复相机运动和重建场景的3-D结构从两个图像与校准相机。

参考文献

[1]哈特利,理查德和安德鲁·齐瑟曼。计算机视觉中的多视图几何。第二版。剑桥,2000年。

Baidu
map