www.pudn.com > 3dRecon.zip > grappleFmatrix.m, change:2004-11-05,size:5922b
%% File: grappleFmatrix
%% A4 2003 handout code
%% Uses RANSAC to estimate F matrix from 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
startup;
cd(dir);
end
reconRoot = [matlabVisRoot '/utvisToolbox/tutorials/3dRecon'];
addpath([reconRoot '/data/wadham']);
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 try.
%% Wadham left image: use wadham/001.jpg
imPath = 'data/wadham/'; fnameLeft = '001';
im = imread([imPath fnameLeft],'jpg');
im = double(im(:,:,2));
imDwn = blurDn(im,1)/2;
imLeft = imDwn;
%% Read correspondence data
load data/wadham/corrPnts5
%% Wadham right image data/wadham002-5.jpg use for corrPnts2-5 respectively
fnameRight = '005';
im = imread([imPath fnameRight],'jpg');
im = double(im(:,:,2));
imDwn = blurDn(im,1)/2;
imRight = imDwn;
clear imPts;
imPts = cat(3, im_pos1', im_pos2');
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
SUPERIMPOSE = TRUE;
hFig = figure(2);
clf;
if SUPERIMPOSE
image(imLeft);
colormap(gray(256));
end
resizeImageFig(hFig, size(imDwn), 1); hold on;
set(get(hFig,'CurrentAxes'),'Ydir','reverse');
hold on;
% Plot all interest point locations as blue .'s
plot(imPts(1,:,1), imPts(2,:,1), '.b');
set(gca,'YDir', 'reverse');
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
SUPERIMPOSE = TRUE;
hFig = figure(3);
clf;
if SUPERIMPOSE
image(imRight);
colormap(gray(256));
end
resizeImageFig(hFig, size(imDwn), 1); hold on;
set(get(hFig,'CurrentAxes'),'Ydir','reverse');
hold on;
% Plot all interest point locations as blue .'s
plot(imPts(1,:,2), imPts(2,:,2), '.b');
set(gca,'YDir', 'reverse');
ax = axis;
cropBox = [ax(1) ax(3) ax(2) ax(4)];
title('Epipolar Lines in Left 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