-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathicp_3dbasic.m
94 lines (71 loc) · 2.07 KB
/
icp_3dbasic.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
function [params, R,t] = icp_3dbasic(model, data)
% ICP_3DLM A function
% ...
% Author: Andrew Fitzgibbon <awf@robots.ox.ac.uk>
% Date: 10 Apr 01
model_centre = mean(model);
model = awf_translate_pts(model, -model_centre);
data_centre = mean(data);
data = awf_translate_pts(data, -data_centre);
lmdata.kdObj = KDTreeSearcher(model);
lmdata.data = data;
figure(1)
hold off
set(scatter(model, 'b.'), 'markersize', .001);
set(gcf, 'renderer', 'opengl')
hold on
axis off
lmdata.h = scatter(data, 'r+');
set(lmdata.h, 'markersize', 2);
axis equal
axis vis3d
global run_icp3d_iter
run_icp3d_iter = 0;
if nargout < 2
disp('No return values, returning....');
return
end
% Set up levmarq and tallyho
options = optimset('lsqnonlin');
options.TypicalX = [1 1 1 1 1 1 1];
options.TolFun = 0.0001;
options.TolX = 0.00001;
options.DiffMinChange = .001;
options.LargeScale = 'on';
params = [0 0 0 1 0 0 0]; % quat, tx, ty, tz
params = lsqnonlin(@(X) icp_3derror(X, lmdata), params, [], [], options);
[R,t] = icp_deparam(params);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Error function
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function dists = icp_3derror(params, lm)
% 1. Extract R, t
[R,t] = icp_deparam(params);
t = t(:)'; % colvec
% 2. Evaluate
D = lm.data;
D = D * R' + t(ones(1, size(D, 1)), :);
[~, dists] = knnsearch(lm.kdObj, D);
stdDists = std(dists);
dists = awf_m_estimator('ls', dists, stdDists);
global run_icp3d_iter
fprintf('Iter %3d ', run_icp3d_iter);
run_icp3d_iter = run_icp3d_iter + 1;
fprintf('%5.2f ', params);
fprintf('err %.2f\n', norm(dists));
set(lm.h, ...
'xdata', D(:, 1), ...
'ydata', D(:, 2), ...
'zdata', D(:, 3));
drawnow
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [R,t] = icp_deparam(p)
p1 = p(1);
p2 = p(2);
p3 = p(3);
p4 = p(4);
p5 = p(5);
p6 = p(6);
p7 = p(7);
R = quat2rot([p1 p2 p3 p4]) / sum([p1 p2 p3 p4].^2);
t = [p5 p6 p7]';