For this project, I worked towards estimating the fundamental matrix, from which we are able to obtain the estimated epipolar lines for an image. I sought to find the best fundamental matrix for different images using point correspondance found with SIFT - the algorithm explored in the previous project. The 3 parts of this project are as follows
To find the projection matrix M, I used the known 2 and 3 dimensional locations and set up my system of equations to solve for M by setting the product equal to 0 and using singular value decomposition as discussed in lecture.
for i=1:size(A,1)/2
j = 2*i-1;
k = 2*i;
A(j, :) = [X(i) Y(i) Z(i) 1 0 0 0 0 ...
-u(i)*X(i) -u(i)*Y(i) -u(i)*Z(i) -u(i)];
disp(A(j,:))
A(k, :) = [0 0 0 0 X(i) Y(i) Z(i) 1 ...
-v(i)*X(i) -v(i)*Y(i) -v(i)*Z(i) -v(i)];
end
[U,S,V] = svd(A);
M = V(:,end);
M = reshape(M,[],3)';
For the example given I found the projection matrix to be
0.4583 -0.2947 -0.0140 0.0040
-0.0509 -0.0546 -0.5411 -0.0524
0.1090 0.1783 -0.0443 0.5968
the camera center: <-1.5127, -2.3517, 0.2826>, and a residual of 0.0445.
To find the fundamental matrix I used the fact that its product with the transpose of the points in one image and the points in the other should equal 0 and set up my system of equations as follows.
for i=1:size(Points_a, 1)
A(i, :) = [u(i)*u_prime(i) v(i)*u_prime(i) u_prime(i) u(i)*v_prime(i) ...
v(i)*v_prime(i) v_prime(i) u(i) v(i) 1];
end
I then took the singular value decomposition of the resulting matrix and used the left singular vectors as my fundamental matrix. I found that the matrix produced was already rank 2, so I did not set the smallest eigen value to 0. The matrix produced was:
-0.0000 0.0000 -0.0019
0.0000 0.0000 0.0172
-0.0009 -0.0264 0.9995
The epipolar lines for the points generated from the fundamental matrix go through the center of each point and represent the points actual location.
To find the best F, I used RANSAC and randomly sampled 8 points then computed the fundamental matrix using those, and then evaluated F according to the number of pFp' pairs < .01 (i.e. the number of inliers).
for i=1:limit
rnd = randsample(size(matches_a,1), N_1);
F = estimate_fundamental_matrix(matches_a(rnd,:), matches_b(rnd,:));
y = evaluate_fundamental_matrix(matches_a, matches_b, F);
thresholded = abs(y) < .01;
inliers = sum(thresholded);
disp(inliers);
if inliers > Best_inliers
Best_inliers = inliers;
Best_y = y;
inliers_idx = find(thresholded);
Best_Fmatrix = F;
end
end
function y = evaluate_fundamental_matrix(Points_a, Points_b, F)
u = Points_a(:, 1);
v = Points_a(:, 2);
u_prime = Points_b(:, 1);
v_prime = Points_b(:, 2);
A = zeros(size(Points_a, 1), 9);
for i=1:size(Points_a, 1)
A(i, :) = [u(i)*u_prime(i) v(i)*u_prime(i) u_prime(i) u(i)*v_prime(i) ...
v(i)*v_prime(i) v_prime(i) u(i) v(i) 1];
end
y = A * reshape(F, [9,1]);
end
With this I was able to obtain a good number of correct matches on the pair of Mt. Rushmore images.
With other image pairs, the points were matched well also even without normalization. However, I believe with normalization, I would have much fewer incorrect matches.