【问题标题】:MATLAB: 3d reconstruction using eight point algorithmMATLAB:使用八点算法进行 3d 重建
【发布时间】:2014-10-31 18:49:34
【问题描述】:

我正在尝试从 2 张图像中实现 3D 重建。我遵循的步骤是,

1. Found corresponding points between 2 images using SURF.
2. Implemented eight point algo to find "Fundamental matrix"
3. Then, I implemented triangulation.

到目前为止,我已经得到了基本矩阵和三角剖分结果。我如何进一步进行 3d 重建?我对互联网上所有可用的材料感到困惑。

另外,这是代码。让我知道这是否正确。

Ia=imread('1.jpg');
Ib=imread('2.jpg');
Ia=rgb2gray(Ia);
Ib=rgb2gray(Ib);
% My surf addition
% collect Interest Points from Each Image
blobs1 = detectSURFFeatures(Ia);
blobs2 = detectSURFFeatures(Ib);
figure;
imshow(Ia);
hold on;
plot(selectStrongest(blobs1, 36));
figure;
imshow(Ib);
hold on;
plot(selectStrongest(blobs2, 36));
title('Thirty strongest SURF features in I2');
[features1, validBlobs1] = extractFeatures(Ia, blobs1);
[features2, validBlobs2] = extractFeatures(Ib, blobs2);
indexPairs = matchFeatures(features1, features2);
matchedPoints1 = validBlobs1(indexPairs(:,1),:);
matchedPoints2 = validBlobs2(indexPairs(:,2),:);
figure;
showMatchedFeatures(Ia, Ib, matchedPoints1, matchedPoints2);
legend('Putatively matched points in I1', 'Putatively matched points in I2');

for i=1:matchedPoints1.Count
    xa(i,:)=matchedPoints1.Location(i);
    ya(i,:)=matchedPoints1.Location(i,2);
    xb(i,:)=matchedPoints2.Location(i);
    yb(i,:)=matchedPoints2.Location(i,2);
end

matchedPoints1.Count
figure(1) ; clf ;
imshow(cat(2, Ia, Ib)) ;
axis image off ;
hold on ;
xbb=xb+size(Ia,2);
set=[1:matchedPoints1.Count];
h = line([xa(set)' ; xbb(set)'], [ya(set)' ; yb(set)']) ;

pts1=[xa,ya];
pts2=[xb,yb];
pts11=pts1;pts11(:,3)=1;
pts11=pts11';
pts22=pts2;pts22(:,3)=1;pts22=pts22';

width=size(Ia,2);
height=size(Ib,1);
F=eightpoint(pts1,pts2,width,height);

[P1new,P2new]=compute2Pmatrix(F);
XP = triangulate(pts11, pts22,P2new);

eightpoint()

function [ F ] = eightpoint( pts1, pts2,width,height)

X = 1:width;
Y = 1:height;
[X, Y] = meshgrid(X, Y);
x0 = [mean(X(:)); mean(Y(:))];
X = X - x0(1);
Y = Y - x0(2);
denom = sqrt(mean(mean(X.^2+Y.^2)));
N = size(pts1, 1);

%Normalized data
T = sqrt(2)/denom*[1 0 -x0(1); 0 1 -x0(2); 0 0 denom/sqrt(2)];
norm_x = T*[pts1(:,1)'; pts1(:,2)'; ones(1, N)];
norm_x_ = T*[pts2(:,1)';pts2(:,2)'; ones(1, N)];
x1 = norm_x(1, :)';
y1= norm_x(2, :)';
x2 = norm_x_(1, :)';
y2 = norm_x_(2, :)';

A = [x1.*x2, y1.*x2, x2, ...
       x1.*y2, y1.*y2, y2, ...
       x1,       y1,     ones(N,1)];

% compute the SVD
[~, ~, V] = svd(A);
F = reshape(V(:,9), 3, 3)';
[FU, FS, FV] = svd(F);
FS(3,3) = 0; %rank 2 constrains
F = FU*FS*FV';

% rescale fundamental matrix
F = T' * F * T;

end

triangulate()

function [ XP ] = triangulate( pts1,pts2,P2 )

n=size(pts1,2);
X=zeros(4,n);
for i=1:n
    A=[-1,0,pts1(1,i),0;
        0,-1,pts1(2,i),0;
        pts2(1,i)*P2(3,:)-P2(1,:);
        pts2(2,i)*P2(3,:)-P2(2,:)];
  [~,~,va] = svd(A);
  X(:,i) = va(:,4);
end
XP(:,:,1) = [X(1,:)./X(4,:);X(2,:)./X(4,:);X(3,:)./X(4,:); X(4,:)./X(4,:)];

end

function [ P1,P2 ] = compute2Pmatrix( F )

P1=[1,0,0,0;0,1,0,0;0,0,1,0];
[~, ~, V] = svd(F');
ep = V(:,3)/V(3,3);
P2 = [skew(ep)*F,ep];
end

【问题讨论】:

  • 计算机视觉工具箱中有一些不错的演示:mathworks.com/help/vision/examples/…mathworks.com/help/vision/examples/…
  • 您的问题是什么? triangulate 是一个函数,给定 imageA 和 imageB 中的一个点以及它们之间的关系,将为您提供一个 3D 的点
  • 我得到了 3D 点。但我不知道如何使用这些点生成纹理 3D 模型。这样最后我就可以看到 3d 重建模型了。

标签: matlab computer-vision matlab-cvst 3d-reconstruction


【解决方案1】:

快速浏览一下,它看起来是正确的。部分注意事项如下:

您在八点()中规范化的代码并不理想。

最好在所涉及的点上完成。每组点都有其缩放矩阵。那就是:

[pts1_n, T1] = normalize_pts(pts1);
[pts2_n, T2] = normalize-pts(pts2);

% ... code
% solution
F = T2' * F * T

作为旁注(为了提高效率),您应该这样做

[~,~,V] = svd(A, 0);

您还希望强制执行基本矩阵秩为 2 的约束。计算出 F 后,您可以:

[U,D,v] = svd(F);
F = U * diag([D(1,1),D(2,2), 0]) * V';

在任何一种情况下,规范化都不是使算法工作的唯一关键。您需要将基本矩阵的估计封装在稳健的估计方案中,如 RANSAC。

像这样的估计问题对非高斯噪声和异常值非常敏感。如果你有少量的错误对应,或者有高错误的点,算法就会中断。

最后,在“三角剖分”中,您要确保点在齐次除法之前不在无穷远处。

我建议使用“合成”数据测试代码。也就是说,生成自己的相机矩阵和对应关系。将它们输入到具有不同噪声水平的估计例程中。在零噪声的情况下,您应该得到一个精确到浮点精度的解决方案。随着噪声的增加,您的估计误差也会增加。

在目前的形式下,在真实数据上运行它可能不会很好,除非您使用 RANSAC 或其他一些稳健的估计器“稳健”算法。

祝你好运。

祝你好运。

【讨论】:

    【解决方案2】:

    您拥有哪个版本的 MATLAB?

    在计算机视觉系统工具箱中有一个名为estimateFundamentalMatrix 的函数,它将为您提供基本矩阵。它可能会给您比您的代码更好的结果,因为它在后台使用 RANSAC,这使得它对虚假匹配具有鲁棒性。还有一个 triangulate 函数,从 R2014b 版本开始。

    你得到的是稀疏的 3D 重建。您可以绘制生成的 3D 点,并且可以将相应像素的颜色映射到每个点。但是,对于您想要的,您必须将曲面或三角形网格拟合到这些点。很遗憾,我无法为您提供帮助。

    【讨论】:

      【解决方案3】:

      如果您要问的是如何从基本矩阵 + 对应点继续到密集模型,那么您还有很多工作要做。

      假设您知道内部相机参数(缩放、旋转、平移),可以从基本矩阵计算相对相机位置 (R,T)。要获得一个完整的密集矩阵,有几种方法可以走。您可以尝试使用现有的库(例如 PMVS)。我会研究 OpenMVG,但我不确定 matlab 接口。

      另一种方法是,您可以计算密集光流(许多可用于 matlab)。寻找极线OF(它需要一个基本矩阵并将解限制在极线上)。然后您可以对每个像素进行三角测量以获得深度图。

      最后,您将不得不使用格式转换来从深度图到 VRML(您可以查看 meshlab)

      对不起,我的回答不是更面向 Matlab。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-12-25
        • 2014-05-25
        • 1970-01-01
        • 1970-01-01
        • 2021-10-26
        • 2017-08-25
        • 2021-08-26
        • 2018-03-08
        相关资源
        最近更新 更多