2014-10-31 8 views
3

Я пытаюсь достичь 3d-реконструкции из 2-х изображений. Следующие шаги я получил,MATLAB: 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 
+2

есть несколько приятных демонстраций от Computer Vision Toolbox: http://www.mathworks.com/help/vision/examples/stereo-calibration-and-scene-reconstruction.html, http://www.mathworks.com /help/vision/examples/sparse-3-d-reconstruction-from-two-views.html – Amro

+0

Каков ваш вопрос? triangulate - это функция, которая, учитывая точку в изображении A и imageB и взаимосвязь между ними, даст вам apointin 3D –

+0

У меня есть 3D-точки. Но я не знаю, как создать текстурированную трехмерную модель, используя эти точки. Так что в конце я вижу 3d реконструированную модель. – nikhilk

ответ

0

Какую версию MATLAB у вас есть?

В панели инструментов компьютера Vision есть функция estimateFundamentalMatrix, которая даст вам основную матрицу. Это может дать вам лучшие результаты, чем ваш код, потому что он использует RANSAC под капотом, что делает его надежным для ложных совпадений. Существует также функция triangulate, начиная с версии R2014b.

Что вы получаете, это редкая 3D-реконструкция. Вы можете построить полученные 3D-точки, и вы можете сопоставить цвет соответствующего пикселя с каждым из них. Однако для того, что вы хотите, вам нужно будет поместить поверхность или треугольную сетку в точки. К сожалению, я не могу вам помочь.

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 или какой-либо другой надежной оценкой.

Удачи.

Удачи.

0

Если вы спрашиваете, как я исхожу от фундаментальной матрицы + соответствующие точки к плотной модели, то у вас еще впереди много работы.

относительные местоположения камеры (R, T) могут быть рассчитаны из фундаментальной матрицы, если вы знаете параметры внутренней камеры (вплоть до масштаба, вращения, перевода). Чтобы получить полную плотную матрицу, есть несколько способов. вы можете попробовать использовать существующую библиотеку (например, PMVS). Я бы посмотрел в OpenMVG, но я не уверен в интерфейсе Matlab.

Еще один способ пойти, вы можете вычислить плотный оптический поток (многие из них доступны для Matlab). Ищите эпиполярность OF (она принимает фундаментальную матрицу и ограничивает решение лежать на эпиполярных линиях). Затем вы можете триангулировать каждый пиксель, чтобы получить карту глубины.

Наконец, вы должны играть с преобразованием форматов, чтобы получить из карты глубины в VRML (Вы можете посмотреть на MeshLab)

К сожалению, мой ответ не более Matlab ориентированные.