www.pudn.com > 3dRecon.zip > dinoTestF.m, change:2004-11-05,size:6665b
%% File: dinoTestF
%% A4 2003 handout code
%% Estimate F matrix from synthetic corresponding points.
%%
%% ADJ, Nov. 03
clear
close all
FALSE = 1 == 0;
TRUE = ~FALSE;
global matlabVisRoot
%% We need to ensure the path is set for the iseToolbox.
if length(matlabVisRoot)==0
dir = pwd;
cd /h/51/jepson/pub/matlab %% CHANGE THIS to your startup directory
startup;
cd(dir);
end
reconRoot = [matlabVisRoot '/utvisToolbox/tutorials/3dRecon'];
addpath([reconRoot '/utils']);
% Random number generator seed:
seed = round(sum(1000*clock));
rand('state', seed);
seed0 = seed;
% We also need to start randn. Use a seedn generated from seed:
seedn = round(rand(1,1) * 1.0e+6);
randn('state', seedn);
nTrial = 10; %% Number of ransac trials to use
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Set up cameras
%% The cameras are automatically rotated by projectDino to fixate
%% on the mean of the 3D points. We do not always want to allow
%% the cameras to move in this fashion (eg. when we change sclZ).
%% So we will compute the rotations for the left and right cameras
%% once and for all, and then use these.
f = 100; % focal length
dLeft = [-50, 0, -150]'; % Center of projection for left camera
dRight = [50, 0, -150]'; % Center of projection for right camera
%% Compute camera rotations to fixate on Dino's center.
[pLeft polys MintLeft MextLeft] = projectDino(f, dLeft, [], 1.0);
Rleft = MextLeft(:, 1:3);
[pRight polys MintRight MextRight] = projectDino(f, dRight, [], 1.0);
Rright = MextRight(:, 1:3);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Generate data...
sclZ = 1.0;
%% Dino left image data
[pLeft polys MintLeft MextLeft] = projectDino(f, dLeft, Rleft, sclZ);
%% Dino right image data
[pRight polys MintRight MextRight] = projectDino(f, dRight, Rright, sclZ);
%% Show left and right images
hFig = figure(1); clf;
plot(pLeft(1,:), pLeft(2,:), '.b');
axis xy; axis equal;
xlabel('X'); ylabel('Y');
axis([-150 150 -100 100]);
title('Left image of Dino');
pause(0.1);
hFig = figure(2); clf;
plot(pRight(1,:), pRight(2,:), '.b');
axis xy; axis equal;
axis([-150 150 -100 100]);
xlabel('X'); ylabel('Y');
title('Right image of Dino');
pause(0.1);
%% Build correspondence data
clear imPts;
imPts = cat(3, pLeft, pRight);
nPts = size(imPts,2);
if size(imPts,1) == 2
imPts = cat(1, imPts, ones(1,nPts,2));
end
%% RANSAC for F
seeds = {};
sigma = 2.0; rho = 2;
for kTrial = 1: nTrial
%% Test out F matrix on a random sample of 8 points
idTest = randperm(nPts);
nTest = min(8, nPts);
idTest = idTest(1:nTest);
%% Solve for F matrix on the random sample
[F Sa Sf] = linEstF(imPts(:,idTest,1), imPts(:,idTest,2),1);
%% Compute perpendicular error of all points to epipolar lines
perpErrL = zeros(1,nPts);
for k = 1:nPts
lk = imPts(:,k,2)' * F';
perpErrL(k) = (lk* imPts(:,k,1))/norm(lk(1:2));
end
%% Detect inliers
idInlier = abs(perpErrL) rho*sigma;
%% Count inliers
nInlier = sum(idInlier);
if nInlier > 20
%% Store sets of sampled points with at least 20 inliers
seed.id = idTest;
seed.idInlier = idInlier;
seed.nInlier = nInlier;
seed.F = F;
kSeed = length(seeds)+1
seeds{kSeed} = seed;
end
end
%% Done RANSAC trials
%% Extract best solution
nInliers = zeros(1, length(seeds));
for ks = 1:length(seeds)
nInliers(ks) = seeds{ks}.nInlier;
end
[nM ks] = max(nInliers);
nInliers(ks)
%% Refine estimate of F using all inliers.
F = seeds{ks}.F;
idInlier = seeds{ks}.idInlier;
idInlierOld = idInlier;
sum(idInlier)
%% Do at most 10 iterations attempting to entrain as many points as possible.
for kIt = 1: 10
%% Fit F using all current inliers
[F Sa Sf] = linEstF(imPts(:,idInlier,1), imPts(:,idInlier,2),1);
%% Compute perpendicular error to epipolar lines
perpErrL = zeros(1,nPts);
for k = 1:nPts
lk = imPts(:,k,2)' * F';
perpErrL(k) = (lk* imPts(:,k,1))/norm(lk(1:2));
end
idInlier = abs(perpErrL) rho*sigma;
nInlier = sum(idInlier)
%% If we have the same set of inliers as the previous iteration then stop.
if all(idInlier == idInlierOld)
break;
end
idInlierOld = idInlier;
end
%%%%%%%%%%%%%%%%%%%%% Plot results
nTest = 64; %% Number of epipolar lines to plot
nCol = 16; %% Number of different colours to use.
col = hsv(nCol); %% Colour map.
%% Random sample the lines to plot
idLines = randperm(nPts);
idLines = idLines(1:nTest);
%% Show left image
hFig = figure(1);
clf; hold on;
% Plot all interest point locations as blue .'s
plot(imPts(1,:,1), imPts(2,:,1), '.b');
axis([-150 150 -100 100]); axis xy; axis equal;
ax = axis;
cropBox = [ax(1) ax(3) ax(2) ax(4)];
title('Epipolar Lines in Left Image');
for kl = 1:length(idLines)
% Plot interest point location corresponding to epipolar line as a "o"
% in the same colour as the epipolar line.
k = idLines(kl);
plot(imPts(1,k,1), imPts(2,k,1), 'o', 'Color', col(mod(k,nCol)+1,:));
% Plot epipolar line.
lk = imPts(:,k,2)' * F';
epk = cropLineInBox(lk(1:2), lk(3), cropBox);
set(line(epk(:,1), epk(:,2)), 'Color', col(mod(k,nCol)+1,:));
end
%% Show right image
hFig = figure(2);
clf; hold on;
% Plot all interest point locations as blue .'s
plot(imPts(1,:,2), imPts(2,:,2), '.b');
axis([-150 150 -100 100]); axis xy; axis equal;
ax = axis;
cropBox = [ax(1) ax(3) ax(2) ax(4)];
title('Epipolar Lines in Right Image');
perpErrR = [];
for kl = 1:length(idLines)
% Plot interest point location corresponding to epipolar line as a "o"
% in the same colour as the epipolar line.
k = idLines(kl);
plot(imPts(1,k,2), imPts(2,k,2), 'o', 'Color', col(mod(k,nCol)+1,:));
% Plot epipolar line.
lk = imPts(:,k,1)' * F;
epk = cropLineInBox(lk(1:2), lk(3), cropBox);
set(line(epk(:,1), epk(:,2)), 'Color', col(mod(k,nCol)+1,:));
perpErrR = [perpErrR (lk * imPts(:,k,2)/norm(lk(1:2)))];
end
%% Compute perpendicular distance to epipolar lines in left and right images.
perpErrL = [];
for k = 1:nPts
lk = imPts(:,k,2)' * F';
perpErrL = [perpErrL (lk * imPts(:,k,1))/norm(lk(1:2))];
end
perpErrR = [];
for k = 1:nPts
lk = imPts(:,k,1)' * F;
perpErrR = [perpErrR (lk * imPts(:,k,2)/norm(lk(1:2)))];
end
%% Plot a histogram of the perpendicular distances
err = [perpErrL perpErrR];
err = min(err, 10);
err = max(err, -10);
[n b] = histo(err, 64);
figure(4); clf;
plot(b,n);
title('Distance to epipolar line');
xlabel('Error in pixels');
ylabel('Frequency');
%% Count inliers
idL = abs(perpErrL) rho*sigma;
idR = abs(perpErrR) rho*sigma;
idInlier = idL & idR;
sum(idInlier)
sum(idInlier)/nPts
%% save 'Fcorr' F Sa Sf idInlier nInliers