-
Notifications
You must be signed in to change notification settings - Fork 2
/
ransacfitfundmatrix.m
168 lines (134 loc) · 5.77 KB
/
ransacfitfundmatrix.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
% RANSACFITFUNDMATRIX - fits fundamental matrix using RANSAC
%
% Usage: [F, inliers] = ransacfitfundmatrix(x1, x2, t)
%
% Arguments:
% x1 - 2xN or 3xN set of homogeneous points. If the data is
% 2xN it is assumed the homogeneous scale factor is 1.
% x2 - 2xN or 3xN set of homogeneous points such that x1<->x2.
% t - The distance threshold between data point and the model
% used to decide whether a point is an inlier or not.
% Note that point coordinates are normalised to that their
% mean distance from the origin is sqrt(2). The value of
% t should be set relative to this, say in the range
% 0.001 - 0.01
%
% Note that it is assumed that the matching of x1 and x2 are putative and it
% is expected that a percentage of matches will be wrong.
%
% Returns:
% F - The 3x3 fundamental matrix such that x2'Fx1 = 0.
% inliers - An array of indices of the elements of x1, x2 that were
% the inliers for the best model.
%
% See Also: RANSAC, FUNDMATRIX
% Copyright (c) 2004-2005 Peter Kovesi
% School of Computer Science & Software Engineering
% The University of Western Australia
% http://www.csse.uwa.edu.au/
%
% Permission is hereby granted, free of charge, to any person obtaining a copy
% of this software and associated documentation files (the "Software"), to deal
% in the Software without restriction, subject to the following conditions:
%
% The above copyright notice and this permission notice shall be included in
% all copies or substantial portions of the Software.
%
% The Software is provided "as is", without warranty of any kind.
% February 2004 Original version
% August 2005 Distance error function changed to match changes in RANSAC
function [F, inliers] = ransacfitfundmatrix(x1, x2, TD1, TD2, t, feedback)
if ~all(size(x1)==size(x2))
error('Data sets x1 and x2 must have the same dimension');
end
if nargin == 3
feedback = 0;
end
[rows,npts] = size(x1);
if rows~=2 & rows~=3
error('x1 and x2 must have 2 or 3 rows');
end
if rows == 2 % Pad data with homogeneous scale factor of 1
x1 = [x1; ones(1,npts)];
x2 = [x2; ones(1,npts)];
end
angular = zeros(1, length(x1));
for n = 1:length(x1)
angular(n) = TD2(:,n)' * TD1(:,n) / ( norm( TD1(:,n) ) * norm( TD2(:,n) ) );
end
% Normalise each set of points so that the origin is at centroid and
% mean distance from origin is sqrt(2). normalise2dpts also ensures the
% scale parameter is 1. Note that 'fundmatrix' will also call
% 'normalise2dpts' but the code in 'ransac' that calls the distance
% function will not - so it is best that we normalise beforehand.
[x1N, T1] = normalise2dpts(x1);
[x2N, T2] = normalise2dpts(x2);
s = 8; % Number of points needed to fit a fundamental matrix. Note that
% only 7 are needed but the function 'fundmatrix' only
% implements the 8-point solution.
fittingfn = @fundmatrix;
distfn = @funddist;
degenfn = @isdegenerate;
% x1 and x2 are 'stacked' to create a 6xN array for ransac
[F, inliers] = ransac([x1N; x2N], fittingfn, distfn, degenfn, s, t, angular, feedback);
%[F, inliers] = ransac2([x1N; x2N], fittingfn, distfn, degenfn, s, pi / 4 , [x1; x2], feedback);
% Now do a final least squares fit on the data points considered to
% be inliers.
%F = fundmatrix(x1N(:,inliers), x2N(:,inliers));
% Denormalise
%F = T2'*F*T1;
F = fundmatrix(x1(:,inliers), x2(:,inliers));
%--------------------------------------------------------------------------
% Function to evaluate the first order approximation of the geometric error
% (Sampson distance) of the fit of a fundamental matrix with respect to a
% set of matched points as needed by RANSAC. See: Hartley and Zisserman,
% 'Multiple View Geometry in Computer Vision', page 270.
%
% Note that this code allows for F being a cell array of fundamental matrices of
% which we have to pick the best one. (A 7 point solution can return up to 3
% solutions)
%{
function [bestInliers, bestF] = funddist(F, x, t)
x1 = x(1:3,:); % Extract x1 and x2 from x
x2 = x(4:6,:);
if iscell(F) % We have several solutions each of which must be tested
nF = length(F); % Number of solutions to test
bestF = F{1}; % Initial allocation of best solution
ninliers = 0; % Number of inliers
for k = 1:nF
x2tFx1 = zeros(1,length(x1));
for n = 1:length(x1)
x2tFx1(n) = x2(:,n)'*F{k}*x1(:,n);
end
Fx1 = F{k}*x1;
Ftx2 = F{k}'*x2;
% Evaluate distances
d = x2tFx1.^2 ./ ...
(Fx1(1,:).^2 + Fx1(2,:).^2 + Ftx2(1,:).^2 + Ftx2(2,:).^2);
inliers = find(abs(d) < t); % Indices of inlying points
if length(inliers) > ninliers % Record best solution
ninliers = length(inliers);
bestF = F{k};
bestInliers = inliers;
end
end
else % We just have one solution
x2tFx1 = zeros(1,length(x1));
for n = 1:length(x1)
x2tFx1(n) = x2(:,n)'*F*x1(:,n);
end
Fx1 = F*x1;
Ftx2 = F'*x2;
% Evaluate distances
d = x2tFx1.^2 ./ ...
(Fx1(1,:).^2 + Fx1(2,:).^2 + Ftx2(1,:).^2 + Ftx2(2,:).^2);
bestInliers = find(abs(d) < t); % Indices of inlying points
bestF = F; % Copy F directly to bestF
end
%}
%----------------------------------------------------------------------
% (Degenerate!) function to determine if a set of matched points will result
% in a degeneracy in the calculation of a fundamental matrix as needed by
% RANSAC. This function assumes this cannot happen...
function r = isdegenerate(x)
r = 0;