This commit is contained in:
Ivan
2022-04-05 11:42:28 +03:00
commit 6dc0eb0fcf
5565 changed files with 1200500 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
function v_noisy = addNoise(v_clean,focal_length,pixel_noise)
%find good vector in normal plane based on good conditioning
inPlaneVector1 = zeros(3,1);
if v_clean(1,1) > v_clean(2,1) && v_clean(1,1) > v_clean(3,1)
inPlaneVector1(2,1) = 1.0;
inPlaneVector1(3,1) = 0.0;
inPlaneVector1(1,1) = 1.0/v_clean(1,1) * (-v_clean(2,1));
else
if v_clean(2,1) > v_clean(3,1) && v_clean(2,1) > v_clean(1,1)
inPlaneVector1(3,1) = 1.0;
inPlaneVector1(1,1) = 0.0;
inPlaneVector1(2,1) = 1.0/v_clean(2,1) * (-v_clean(3,1));
else
%v_clean(3,1) > v_clean(1,1) && v_clean(3,1) > v_clean(2,1)
inPlaneVector1(1,1) = 1.0;
inPlaneVector1(2,1) = 0.0;
inPlaneVector1(3,1) = 1.0/v_clean(3,1) * (-v_clean(1,1));
end
end
%normalize the in-plane vector
inPlaneVector1 = inPlaneVector1 / norm(inPlaneVector1);
inPlaneVector2 = cross(v_clean,inPlaneVector1);
noiseX = pixel_noise * (rand-0.5)*2.0;% / sqrt(2);
noiseY = pixel_noise * (rand-0.5)*2.0;% / sqrt(2);
v_noisy = focal_length * v_clean + noiseX * inPlaneVector1 + noiseY * inPlaneVector2;
v_noisy_norm = norm(v_noisy);
v_noisy = v_noisy ./ v_noisy_norm;
end

View File

@@ -0,0 +1,20 @@
function R = cayley2rot(v)
cayley0 = v(1,1);
cayley1 = v(2,1);
cayley2 = v(3,1);
R = zeros(3,3);
scale = 1+cayley0^2+cayley1^2+cayley2^2;
R(1,1) = 1+cayley0^2-cayley1^2-cayley2^2;
R(1,2) = 2*(cayley0*cayley1-cayley2);
R(1,3) = 2*(cayley0*cayley2+cayley1);
R(2,1) = 2*(cayley0*cayley1+cayley2);
R(2,2) = 1-cayley0^2+cayley1^2-cayley2^2;
R(2,3) = 2*(cayley1*cayley2-cayley0);
R(3,1) = 2*(cayley0*cayley2-cayley1);
R(3,2) = 2*(cayley1*cayley2+cayley0);
R(3,3) = 1-cayley0^2-cayley1^2+cayley2^2;
R = (1/scale) * R;

View File

@@ -0,0 +1,128 @@
function [v1, v2, t, R ] = create2D2DExperiment( pt_number, cam_number, noise, outlier_fraction )
%% generate the camera system
avg_cam_distance = 0.5;
cam_offsets = zeros(3,cam_number);
%cam_rotations = zeros(3,cam_number*3);
if cam_number == 1
cam_offsets = zeros(3,1);
%cam_rotations = eye(3);
else
for i=1:cam_number
cam_offsets(:,i) = avg_cam_distance * generateRandomR() * [1.0; 0.0; 0.0];
%cam_rotations(:,(i-1)*3+1:(i-1)*3+3) = generateRandomR();
end
end
%% generate random view-points
max_parallax = 2.0;
max_rotation = 0.5;
position1 = zeros(3,1);
rotation1 = eye(3);
position2 = max_parallax * 2.0 * (rand(3,1) - repmat(0.5,3,1));
rotation2 = generateBoundedR(max_rotation);
%% Generate random point-cloud
minDepth = 4.0;
maxDepth = 8.0;
normalizedPoints = 2.0*(rand(3,pt_number)-repmat(0.5,3,pt_number));
norms = sqrt(sum(normalizedPoints.*normalizedPoints));
directions = normalizedPoints./repmat(norms,3,1);
points = (maxDepth-minDepth) * normalizedPoints + minDepth * directions;
%% Now create the correspondences by looping through the cameras
focal_length = 800.0;
v1 = zeros(6,pt_number);
v2 = zeros(6,pt_number);
cam_correspondence = 1;
cam_correspondences = zeros(1,pt_number);
for i=1:pt_number
cam_offset = cam_offsets(:,cam_correspondence);
%cam_rotation = cam_rotations(:,(cam_correspondence-1)*3+1:(cam_correspondence-1)*3+3);
body_point1 = rotation1' * (points(:,i)-position1);
body_point2 = rotation2' * (points(:,i)-position2);
% we actually omit the can rotation here by unrotating the bearing
% vectors already
bearingVector1 = body_point1 - cam_offset;
bearingVector2 = body_point2 - cam_offset;
bearingVector1_norm = norm(bearingVector1);
bearingVector2_norm = norm(bearingVector2);
bearingVector1 = bearingVector1/bearingVector1_norm;
bearingVector2 = bearingVector2/bearingVector2_norm;
% add noise to the bearing vectors here
bearingVector1_noisy = addNoise(bearingVector1,focal_length,noise);
bearingVector2_noisy = addNoise(bearingVector2,focal_length,noise);
% store the normalized bearing vectors along with the cameras they are
% being seen (we create correspondences that always originate from the
% same camera, you can change this if you want)
bearingVector1_norm = norm(bearingVector1_noisy);
bearingVector2_norm = norm(bearingVector2_noisy);
v1(:,i) = [bearingVector1_noisy./bearingVector1_norm; cam_offset];
v2(:,i) = [bearingVector2_noisy./bearingVector2_norm; cam_offset];
% change the camera correspondence
cam_correspondences(1,i) = cam_correspondence;
cam_correspondence = cam_correspondence + 1;
if cam_correspondence > cam_number
cam_correspondence = 1;
end
end
%% Add outliers
number_outliers = floor(outlier_fraction*pt_number);
if number_outliers > 0
for i=1:number_outliers
cam_correspondence = cam_correspondences(1,i);
cam_offset = cam_offsets(:,cam_correspondence);
%cam_rotation = cam_rotations(:,(cam_correspondence-1)*3+1:(cam_correspondence-1)*3+3);
%generate random point
normalizedPoint = 2.0*(rand(3,1)-repmat(0.5,3,1));
norm1 = sqrt(sum(normalizedPoint.*normalizedPoint));
direction = normalizedPoint./norm1;
point = (maxDepth-minDepth) * normalizedPoint + minDepth * direction;
body_point2 = rotation2' * (point-position2);
% store the point (no need to add noise)
bearingVector2 = body_point2 - cam_offset;
% store the normalized bearing vectors along with the cameras they are
% being seen (we create correspondences that always originate from the
% same camera, you can change this if you want)
bearingVector2_norm = norm(bearingVector2);
v2(:,i) = [bearingVector2./bearingVector2_norm; cam_offset];
end
end
%% compute relative translation and rotation
R = rotation1' * rotation2;
t = rotation1' * (position2 - position1);
%% Cut the cam offset in the single camera case (e.g. central)
if cam_number == 1
v1 = v1(1:3,:);
v2 = v2(1:3,:);
end

View File

@@ -0,0 +1,118 @@
function [v1, v2, t, R ] = create2D2DOmniExperiment( pt_number, cam_number, noise, outlier_fraction )
%% generate the camera system
cam_distance = 1.0;
%% set a regular camera system with 2 or 4 cameras here
if cam_number == 2
cam_offsets = [ cam_distance -cam_distance; 0.0 0.0; 0.0 0.0 ];
else
cam_number = 4; % only two or 4 supported for this experiment
cam_offsets = [ cam_distance 0.0 -cam_distance 0.0; 0.0 cam_distance 0.0 -cam_distance; 0.0 0.0 0.0 0.0 ];
end
%% generate random view-points
max_parallax = 2.0;
max_rotation = 0.5;
position1 = zeros(3,1);
rotation1 = eye(3);
position2 = max_parallax * 2.0 * (rand(3,1) - repmat(0.5,3,1));
rotation2 = generateBoundedR(max_rotation);
%% Generate random point-cloud
avg_depth_over_cam_distance = 10.0;
maxDepth = 5.0;
normalizedPoints = 2.0*(rand(3,pt_number)-repmat(0.5,3,pt_number));
points = maxDepth * normalizedPoints;
%% Now create the correspondences by looping through the cameras
focal_length = 800.0;
v1 = zeros(6,pt_number);
v2 = zeros(6,pt_number);
cam_correspondence = 1;
cam_correspondences = zeros(1,pt_number);
for i=1:pt_number
cam_offset = cam_offsets(:,cam_correspondence);
%cam_rotation = cam_rotations(:,(cam_correspondence-1)*3+1:(cam_correspondence-1)*3+3);
%special: shift the point in the first frame along current camera axis, which guarantees homogeneous distribution
temp = points(:,i) + avg_depth_over_cam_distance * cam_offset;
points(:,i) = temp;
body_point1 = rotation1' * (points(:,i)-position1);
body_point2 = rotation2' * (points(:,i)-position2);
% we actually omit the can rotation here by unrotating the bearing
% vectors already
bearingVector1 = body_point1 - cam_offset;
bearingVector2 = body_point2 - cam_offset;
bearingVector1_norm = norm(bearingVector1);
bearingVector2_norm = norm(bearingVector2);
bearingVector1 = bearingVector1/bearingVector1_norm;
bearingVector2 = bearingVector2/bearingVector2_norm;
% add noise to the bearing vectors here
bearingVector1_noisy = addNoise(bearingVector1,focal_length,noise);
bearingVector2_noisy = addNoise(bearingVector2,focal_length,noise);
% store the normalized bearing vectors along with the cameras they are
% being seen (we create correspondences that always originate from the
% same camera, you can change this if you want)
bearingVector1_norm = norm(bearingVector1_noisy);
bearingVector2_norm = norm(bearingVector2_noisy);
v1(:,i) = [bearingVector1_noisy./bearingVector1_norm; cam_offset];
v2(:,i) = [bearingVector2_noisy./bearingVector2_norm; cam_offset];
% change the camera correspondence
cam_correspondences(1,i) = cam_correspondence;
cam_correspondence = cam_correspondence + 1;
if cam_correspondence > cam_number
cam_correspondence = 1;
end
end
%% Add outliers
number_outliers = floor(outlier_fraction*pt_number);
if number_outliers > 0
for i=1:number_outliers
cam_correspondence = cam_correspondences(1,i);
cam_offset = cam_offsets(:,cam_correspondence);
%cam_rotation = cam_rotations(:,(cam_correspondence-1)*3+1:(cam_correspondence-1)*3+3);
%generate random point
normalizedPoint = 2.0*(rand(3,1)-repmat(0.5,3,1));
point = maxDepth * normalizedPoint + avg_depth_over_cam_distance * cam_offset;
body_point2 = rotation2' * (point-position2);
% store the point (no need to add noise)
bearingVector2 = body_point2 - cam_offset;
% store the normalized bearing vectors along with the cameras they are
% being seen (we create correspondences that always originate from the
% same camera, you can change this if you want)
bearingVector2_norm = norm(bearingVector2);
v2(:,i) = [bearingVector2./bearingVector2_norm; cam_offset];
end
end
%% compute relative translation and rotation
R = rotation1' * rotation2;
t = rotation1' * (position2 - position1);

View File

@@ -0,0 +1,116 @@
function [points, v, t, R ] = create2D3DExperiment( pt_number, cam_number, noise, outlier_fraction )
%% generate the camera system
avg_cam_distance = 0.5;
cam_offsets = zeros(3,cam_number);
%cam_rotations = zeros(3,cam_number*3);
if cam_number == 1
cam_offsets = zeros(3,1);
%cam_rotations = eye(3);
else
for i=1:cam_number
cam_offsets(:,i) = avg_cam_distance * generateRandomR() * [1.0; 0.0; 0.0];
%cam_rotations(:,(i-1)*3+1:(i-1)*3+3) = generateRandomR();
end
end
%% generate random view-points
max_parallax = 2.0;
max_rotation = 0.5;
position = max_parallax * 2.0 * (rand(3,1) - repmat(0.5,3,1));
rotation = generateBoundedR(max_rotation);
%% Generate random point-cloud
minDepth = 4.0;
maxDepth = 8.0;
normalizedPoints = 2.0*(rand(3,pt_number)-repmat(0.5,3,pt_number));
norms = sqrt(sum(normalizedPoints.*normalizedPoints));
directions = normalizedPoints./repmat(norms,3,1);
points = (maxDepth-minDepth) * normalizedPoints + minDepth * directions;
%% Now create the correspondences by looping through the cameras
focal_length = 800.0;
v = zeros(6,pt_number);
cam_correspondence = 1;
cam_correspondences = zeros(1,pt_number);
for i=1:pt_number
cam_offset = cam_offsets(:,cam_correspondence);
%cam_rotation = cam_rotations(:,(cam_correspondence-1)*3+1:(cam_correspondence-1)*3+3);
body_point = rotation' * (points(:,i)-position);
% we actually omit the can rotation here by unrotating the bearing
% vectors already
bearingVector = body_point - cam_offset;
bearingVector_norm = norm(bearingVector);
bearingVector = bearingVector/bearingVector_norm;
% add noise to the bearing vectors here
bearingVector_noisy = addNoise(bearingVector,focal_length,noise);
% store the normalized bearing vectors along with the cameras they are
% being seen (we create correspondences that always originate from the
% same camera, you can change this if you want)
bearingVector_norm = norm(bearingVector_noisy);
v(:,i) = [bearingVector_noisy./bearingVector_norm; cam_offset];
% change the camera correspondence
cam_correspondences(1,i) = cam_correspondence;
cam_correspondence = cam_correspondence + 1;
if cam_correspondence > cam_number
cam_correspondence = 1;
end
end
%% Add outliers
number_outliers = floor(outlier_fraction*pt_number);
if number_outliers > 0
for i=1:number_outliers
cam_correspondence = cam_correspondences(1,i);
cam_offset = cam_offsets(:,cam_correspondence);
%cam_rotation = cam_rotations(:,(cam_correspondence-1)*3+1:(cam_correspondence-1)*3+3);
%generate random point
normalizedPoint = 2.0*(rand(3,1)-repmat(0.5,3,1));
norm1 = sqrt(sum(normalizedPoint.*normalizedPoint));
direction = normalizedPoint./norm1;
point = (maxDepth-minDepth) * normalizedPoint + minDepth * direction;
body_point = rotation' * (point-position);
% store the point (no need to add noise)
bearingVector = body_point - cam_offset;
% store the normalized bearing vectors along with the cameras they are
% being seen (we create correspondences that always originate from the
% same camera, you can change this if you want)
bearingVector_norm = norm(bearingVector);
v(:,i) = [bearingVector./bearingVector_norm; cam_offset];
end
end
%% copy over the position and orientation
t = position;
R = rotation;
%% cut the cam offsets in the single camera (e.g. central case)
if cam_number == 1
v = v(1:3,:);
end

View File

@@ -0,0 +1,119 @@
function [v1, v2, cam_offsets, t, R ] = createMulti2D2DExperiment( pt_per_cam, cam_number, noise, outlier_fraction )
%% generate the camera system
avg_cam_distance = 0.5;
cam_offsets = zeros(3,cam_number);
%cam_rotations = zeros(3,cam_number*3);
if cam_number == 1
cam_offsets = zeros(3,1);
%cam_rotations = eye(3);
else
for i=1:cam_number
cam_offsets(:,i) = avg_cam_distance * generateRandomR() * [1.0; 0.0; 0.0];
%cam_rotations(:,(i-1)*3+1:(i-1)*3+3) = generateRandomR();
end
end
%% generate random view-points
max_parallax = 2.0;
max_rotation = 0.5;
position1 = zeros(3,1);
rotation1 = eye(3);
position2 = max_parallax * 2.0 * (rand(3,1) - repmat(0.5,3,1));
rotation2 = generateBoundedR(max_rotation);
%% Generate random point-clouds
minDepth = 4.0;
maxDepth = 8.0;
p = cell([cam_number 1]);
for cam=1:cam_number
normalizedPoints = 2.0*(rand(3,pt_per_cam)-repmat(0.5,3,pt_per_cam));
norms = sqrt(sum(normalizedPoints.*normalizedPoints));
directions = normalizedPoints./repmat(norms,3,1);
p{cam,1} = (maxDepth-minDepth) * normalizedPoints + minDepth * directions;
end
%% Now create the correspondences by looping through the cameras
focal_length = 800.0;
v1 = cell([cam_number 1]);
v2 = cell([cam_number 1]);
for cam=1:cam_number
v1{cam,1} = zeros(3,pt_per_cam);
v2{cam,1} = zeros(3,pt_per_cam);
for i=1:pt_per_cam
cam_offset = cam_offsets(:,cam);
%cam_rotation = cam_rotations(:,(cam-1)*3+1:(cam-1)*3+3);
body_point1 = rotation1' * (p{cam,1}(:,i)-position1);
body_point2 = rotation2' * (p{cam,1}(:,i)-position2);
% we actually omit the cam rotation here by unrotating the bearing
% vectors already
bearingVector1 = body_point1 - cam_offset;
bearingVector2 = body_point2 - cam_offset;
bearingVector1_norm = norm(bearingVector1);
bearingVector2_norm = norm(bearingVector2);
bearingVector1 = bearingVector1/bearingVector1_norm;
bearingVector2 = bearingVector2/bearingVector2_norm;
% add noise to the bearing vectors here
bearingVector1_noisy = addNoise(bearingVector1,focal_length,noise);
bearingVector2_noisy = addNoise(bearingVector2,focal_length,noise);
% store the normalized bearing vectors along with the cameras they are
% being seen (we create correspondences that always originate from the
% same camera, you should not change this in this experiment!)
bearingVector1_norm = norm(bearingVector1_noisy);
bearingVector2_norm = norm(bearingVector2_noisy);
v1{cam,1}(:,i) = bearingVector1_noisy./bearingVector1_norm;
v2{cam,1}(:,i) = bearingVector2_noisy./bearingVector2_norm;
end
end
%% Add outliers
outliers_per_cam = floor(outlier_fraction*pt_per_cam);
if outliers_per_cam > 0
for cam=1:cam_number
for i=1:outliers_per_cam
cam_offset = cam_offsets(:,cam);
%cam_rotation = cam_rotations(:,(cam-1)*3+1:(cam-1)*3+3);
%generate random point
normalizedPoint = 2.0*(rand(3,1)-repmat(0.5,3,1));
norm1 = sqrt(sum(normalizedPoint.*normalizedPoint));
direction = normalizedPoint./norm1;
point = (maxDepth-minDepth) * normalizedPoint + minDepth * direction;
body_point2 = rotation2' * (point-position2);
% store the point (no need to add noise)
bearingVector2 = body_point2 - cam_offset;
bearingVector2_norm = norm(bearingVector2);
v2{cam,1}(:,i) = bearingVector2./bearingVector2_norm;
end
end
end
%% compute relative translation and rotation
R = rotation1' * rotation2;
t = rotation1' * (position2 - position1);

View File

@@ -0,0 +1,120 @@
function [v1, v2, cam_offsets, t, R ] = createMulti2D2DOmniExperiment( pt_per_cam, cam_number, noise, outlier_fraction )
%% generate the camera system
cam_distance = 1.0;
%% set a regular camera system with 2 or 4 cameras here
if cam_number == 2
cam_offsets = [ cam_distance -cam_distance; 0.0 0.0; 0.0 0.0 ];
else
cam_number = 4; % only two or 4 supported for this experiment
cam_offsets = [ cam_distance 0.0 -cam_distance 0.0; 0.0 cam_distance 0.0 -cam_distance; 0.0 0.0 0.0 0.0 ];
end
%% generate random view-points
max_parallax = 2.0;
max_rotation = 0.5;
position1 = zeros(3,1);
rotation1 = eye(3);
position2 = max_parallax * 2.0 * (rand(3,1) - repmat(0.5,3,1));
rotation2 = generateBoundedR(max_rotation);
%% Generate random point-cloud
avg_depth_over_cam_distance = 10.0;
maxDepth = 5.0;
p = cell([cam_number 1]);
for cam=1:cam_number
normalizedPoints = 2.0*(rand(3,pt_per_cam)-repmat(0.5,3,pt_per_cam));
p{cam,1} = maxDepth * normalizedPoints;
end
%% Now create the correspondences by looping through the cameras
focal_length = 800.0;
v1 = cell([cam_number 1]);
v2 = cell([cam_number 1]);
for cam=1:cam_number
v1{cam,1} = zeros(3,pt_per_cam);
v2{cam,1} = zeros(3,pt_per_cam);
for i=1:pt_per_cam
cam_offset = cam_offsets(:,cam);
%special: shift the point in the first frame along current camera axis, which guarantees homogeneous distribution
temp = p{cam,1}(:,i) + avg_depth_over_cam_distance * cam_offset;
p{cam,1}(:,i) = temp;
body_point1 = rotation1' * (p{cam,1}(:,i)-position1);
body_point2 = rotation2' * (p{cam,1}(:,i)-position2);
% we actually omit the can rotation here by unrotating the bearing
% vectors already
bearingVector1 = body_point1 - cam_offset;
bearingVector2 = body_point2 - cam_offset;
bearingVector1_norm = norm(bearingVector1);
bearingVector2_norm = norm(bearingVector2);
bearingVector1 = bearingVector1/bearingVector1_norm;
bearingVector2 = bearingVector2/bearingVector2_norm;
% add noise to the bearing vectors here
bearingVector1_noisy = addNoise(bearingVector1,focal_length,noise);
bearingVector2_noisy = addNoise(bearingVector2,focal_length,noise);
% store the normalized bearing vectors along with the cameras they are
% being seen (we create correspondences that always originate from the
% same camera, you can change this if you want)
bearingVector1_norm = norm(bearingVector1_noisy);
bearingVector2_norm = norm(bearingVector2_noisy);
v1{cam,1}(:,i) = [bearingVector1_noisy./bearingVector1_norm];
v2{cam,1}(:,i) = [bearingVector2_noisy./bearingVector2_norm];
end
end
%% Add outliers
outliers_per_cam = floor(outlier_fraction*pt_per_cam);
if outliers_per_cam > 0
for cam=1:cam_number
for i=1:outliers_per_cam
cam_offset = cam_offsets(:,cam);
%generate random point
normalizedPoint = 2.0*(rand(3,1)-repmat(0.5,3,1));
point = maxDepth * normalizedPoint + avg_depth_over_cam_distance * cam_offset;
body_point2 = rotation2' * (point-position2);
% store the point (no need to add noise)
bearingVector2 = body_point2 - cam_offset;
% store the normalized bearing vectors along with the cameras they are
% being seen (we create correspondences that always originate from the
% same camera, you can change this if you want)
bearingVector2_norm = norm(bearingVector2);
v2{cam,1}(:,i) = [bearingVector2./bearingVector2_norm];
end
end
end
%% compute relative translation and rotation
R = rotation1' * rotation2;
t = rotation1' * (position2 - position1);

View File

@@ -0,0 +1,38 @@
function rotation_error = evaluateRotationError(R_gt,R)
temp = size(size(R));
numberSolutions = 1;
if temp(1,2) == 3
temp2 = size(R);
numberSolutions = temp2(1,3);
end
if numberSolutions == 1
%rotation_error = norm(rodrigues(R_gt'*R));
rotation_error = norm( rodrigues(R_gt) - rodrigues(R) );
else
rotation_errors = zeros(1,numberSolutions);
index = 0;
for i=1:numberSolutions
%Check if there is any Nan
if ~isnan(R(1,1,i))
index = index + 1;
%rotation_errors(1,index) = norm(rodrigues(R_gt'*R(:,:,i)));
rotation_errors(1,index) = norm( rodrigues(R_gt) - rodrigues(R(:,:,i)) );
end
end
%find the smallest error (we are the most "nice" to algorithms returning multiple solutions,
%and do the disambiguation by hand)
[~,minIndex] = min(rotation_errors(1,1:index));
rotation_error = rotation_errors(1,minIndex);
end
end

View File

@@ -0,0 +1,40 @@
function [position_error,rotation_error] = evaluateTransformationError(T_gt,T)
temp = size(size(T));
numberSolutions = 1;
if temp(1,2) == 3
temp2 = size(T);
numberSolutions = temp2(1,3);
end
if numberSolutions == 1
position_error = norm(T_gt(:,4)-T(:,4));
rotation_error = norm(rodrigues(T_gt(:,1:3)'*T(:,1:3)));
else
position_errors = zeros(1,numberSolutions);
rotation_errors = zeros(1,numberSolutions);
index = 0;
for i=1:numberSolutions
%Check if there is any Nan
if ~isnan(T(1,1,i))
index = index + 1;
position_errors(1,index) = norm(T_gt(:,4)-T(:,4,i));
rotation_errors(1,index) = norm(rodrigues(T_gt(:,1:3)'*T(:,1:3,i)));
end
end
%find the smallest error (we are the most "nice" to algorithms returning multiple solutions,
%and do the disambiguation by hand)
[~,minIndex] = min(position_errors(1,1:index));
position_error = position_errors(1,minIndex);
rotation_error = rotation_errors(1,minIndex);
end
end

View File

@@ -0,0 +1,26 @@
function R = generateBoundedR( bound )
rpy = bound*2.0*(rand(3,1)-repmat(0.5,3,1));
R1 = zeros(3,3);
R1(1,1) = 1.0;
R1(2,2) = cos(rpy(1,1));
R1(2,3) = -sin(rpy(1,1));
R1(3,2) = -R1(2,3);
R1(3,3) = R1(2,2);
R2 = zeros(3,3);
R2(1,1) = cos(rpy(2,1));
R2(1,3) = sin(rpy(2,1));
R2(2,2) = 1.0;
R2(3,1) = -R2(1,3);
R2(3,3) = R2(1,1);
R3 = zeros(3,3);
R3(1,1) = cos(rpy(3,1));
R3(1,2) = -sin(rpy(3,1));
R3(2,1) =-R3(1,2);
R3(2,2) = R3(1,1);
R3(3,3) = 1.0;
R = R3 * R2 * R1;
end

View File

@@ -0,0 +1,27 @@
function R = generateRandomR()
rpy = pi()*2.0*(rand(3,1)-repmat(0.5,3,1));
rpy(2,1) = 0.5*rpy(2,1);
R1 = zeros(3,3);
R1(1,1) = 1.0;
R1(2,2) = cos(rpy(1,1));
R1(2,3) = -sin(rpy(1,1));
R1(3,2) = -R1(2,3);
R1(3,3) = R1(2,2);
R2 = zeros(3,3);
R2(1,1) = cos(rpy(2,1));
R2(1,3) = sin(rpy(2,1));
R2(2,2) = 1.0;
R2(3,1) = -R2(1,3);
R2(3,3) = R2(1,1);
R3 = zeros(3,3);
R3(1,1) = cos(rpy(3,1));
R3(1,2) = -sin(rpy(3,1));
R3(2,1) =-R3(1,2);
R3(2,2) = R3(1,1);
R3(3,3) = 1.0;
R = R3 * R2 * R1;
end

View File

@@ -0,0 +1,12 @@
function [t_perturbed,R_perturbed] = perturb(t,R,amplitude)
t_perturbed = t;
r = rodrigues(R);
for i=1:3
t_perturbed(i,1) = t_perturbed(i,1) + (rand-0.5)*2.0*amplitude;
r(i,1) = r(i,1) + (rand-0.5)*2.0*amplitude;
end
R_perturbed = rodrigues(r);
end

View File

@@ -0,0 +1,220 @@
function [out,dout]=rodrigues(in)
% RODRIGUES Transform rotation matrix into rotation vector and viceversa.
%
% Sintax: [OUT]=RODRIGUES(IN)
% If IN is a 3x3 rotation matrix then OUT is the
% corresponding 3x1 rotation vector
% if IN is a rotation 3-vector then OUT is the
% corresponding 3x3 rotation matrix
%
%%
%% Copyright (c) March 1993 -- Pietro Perona
%% California Institute of Technology
%%
%% ALL CHECKED BY JEAN-YVES BOUGUET, October 1995.
%% FOR ALL JACOBIAN MATRICES !!! LOOK AT THE TEST AT THE END !!
%% BUG when norm(om)=pi fixed -- April 6th, 1997;
%% Jean-Yves Bouguet
%% Add projection of the 3x3 matrix onto the set of special ortogonal matrices SO(3) by SVD -- February 7th, 2003;
%% Jean-Yves Bouguet
[m,n] = size(in);
%bigeps = 10e+4*eps;
bigeps = 10e+20*eps;
if ((m==1) & (n==3)) | ((m==3) & (n==1)) %% it is a rotation vector
theta = norm(in);
if theta < eps
R = eye(3);
%if nargout > 1,
dRdin = [0 0 0;
0 0 1;
0 -1 0;
0 0 -1;
0 0 0;
1 0 0;
0 1 0;
-1 0 0;
0 0 0];
%end;
else
if n==length(in) in=in'; end; %% make it a column vec. if necess.
%m3 = [in,theta]
dm3din = [eye(3);in'/theta];
omega = in/theta;
%m2 = [omega;theta]
dm2dm3 = [eye(3)/theta -in/theta^2; zeros(1,3) 1];
alpha = cos(theta);
beta = sin(theta);
gamma = 1-cos(theta);
omegav=[[0 -omega(3) omega(2)];[omega(3) 0 -omega(1)];[-omega(2) omega(1) 0 ]];
A = omega*omega';
%m1 = [alpha;beta;gamma;omegav;A];
dm1dm2 = zeros(21,4);
dm1dm2(1,4) = -sin(theta);
dm1dm2(2,4) = cos(theta);
dm1dm2(3,4) = sin(theta);
dm1dm2(4:12,1:3) = [0 0 0 0 0 1 0 -1 0;
0 0 -1 0 0 0 1 0 0;
0 1 0 -1 0 0 0 0 0]';
w1 = omega(1);
w2 = omega(2);
w3 = omega(3);
dm1dm2(13:21,1) = [2*w1;w2;w3;w2;0;0;w3;0;0];
dm1dm2(13: 21,2) = [0;w1;0;w1;2*w2;w3;0;w3;0];
dm1dm2(13:21,3) = [0;0;w1;0;0;w2;w1;w2;2*w3];
R = eye(3)*alpha + omegav*beta + A*gamma;
dRdm1 = zeros(9,21);
dRdm1([1 5 9],1) = ones(3,1);
dRdm1(:,2) = omegav(:);
dRdm1(:,4:12) = beta*eye(9);
dRdm1(:,3) = A(:);
dRdm1(:,13:21) = gamma*eye(9);
dRdin = dRdm1 * dm1dm2 * dm2dm3 * dm3din;
end;
out = R;
dout = dRdin;
%% it is prob. a rot matr.
elseif ((m==n) & (m==3) & (norm(in' * in - eye(3)) < bigeps)...
& (abs(det(in)-1) < bigeps))
R = in;
% project the rotation matrix to SO(3);
[U,S,V] = svd(R);
R = U*V';
tr = (trace(R)-1)/2;
dtrdR = [1 0 0 0 1 0 0 0 1]/2;
theta = real(acos(tr));
if sin(theta) >= 1e-5,
dthetadtr = -1/sqrt(1-tr^2);
dthetadR = dthetadtr * dtrdR;
% var1 = [vth;theta];
vth = 1/(2*sin(theta));
dvthdtheta = -vth*cos(theta)/sin(theta);
dvar1dtheta = [dvthdtheta;1];
dvar1dR = dvar1dtheta * dthetadR;
om1 = [R(3,2)-R(2,3), R(1,3)-R(3,1), R(2,1)-R(1,2)]';
dom1dR = [0 0 0 0 0 1 0 -1 0;
0 0 -1 0 0 0 1 0 0;
0 1 0 -1 0 0 0 0 0];
% var = [om1;vth;theta];
dvardR = [dom1dR;dvar1dR];
% var2 = [om;theta];
om = vth*om1;
domdvar = [vth*eye(3) om1 zeros(3,1)];
dthetadvar = [0 0 0 0 1];
dvar2dvar = [domdvar;dthetadvar];
out = om*theta;
domegadvar2 = [theta*eye(3) om];
dout = domegadvar2 * dvar2dvar * dvardR;
else
if tr > 0; % case norm(om)=0;
out = [0 0 0]';
dout = [0 0 0 0 0 1/2 0 -1/2 0;
0 0 -1/2 0 0 0 1/2 0 0;
0 1/2 0 -1/2 0 0 0 0 0];
else % case norm(om)=pi; %% fixed April 6th
out = theta * (sqrt((diag(R)+1)/2).*[1;2*(R(1,2:3)>=0)'-1]);
%keyboard;
if nargout > 1,
fprintf(1,'WARNING!!!! Jacobian domdR undefined!!!\n');
dout = NaN*ones(3,9);
end;
end;
end;
else
error('Neither a rotation matrix nor a rotation vector were provided');
end;
return;
%% test of the Jacobians:
%%%% TEST OF dRdom:
om = randn(3,1);
dom = randn(3,1)/1000000;
[R1,dR1] = rodrigues(om);
R2 = rodrigues(om+dom);
R2a = R1 + reshape(dR1 * dom,3,3);
gain = norm(R2 - R1)/norm(R2 - R2a)
%%% TEST OF dOmdR:
om = randn(3,1);
R = rodrigues(om);
dom = randn(3,1)/10000;
dR = rodrigues(om+dom) - R;
[omc,domdR] = rodrigues(R);
[om2] = rodrigues(R+dR);
om_app = omc + domdR*dR(:);
gain = norm(om2 - omc)/norm(om2 - om_app)
%%% OTHER BUG: (FIXED NOW!!!)
omu = randn(3,1);
omu = omu/norm(omu)
om = pi*omu;
[R,dR]= rodrigues(om);
[om2] = rodrigues(R);
[om om2]
%%% NORMAL OPERATION
om = randn(3,1);
[R,dR]= rodrigues(om);
[om2] = rodrigues(R);
[om om2]

View File

@@ -0,0 +1,12 @@
function v = rot2cayley(R)
C1 = R-eye(3);
C2 = R+eye(3);
C = C1 * inv(C2);
v = zeros(3,1);
v(1,1) = -C(2,3);
v(2,1) = C(1,3);
v(3,1) = -C(1,2);
end

View File

@@ -0,0 +1,53 @@
function Rs = transformEssentials(Es)
temp = size(size(Es));
numberSolutions = 1;
if temp(1,2) == 3
temp2 = size(Es);
numberSolutions = temp2(1,3);
end
if numberSolutions == 1
Rs = zeros(3,3,2);
[U,~,V] = svd(Es);
W = [0 -1 0; 1 0 0; 0 0 1];
Rs(1:3,1:3) = U * W * V';
Rs(1:3,4:6) = U * W' * V';
if( det(Rs(1:3,1:3)) < 0 )
Rs(1:3,1:3) = -Rs(1:3,1:3);
end
if( det(Rs(1:3,4:6)) < 0 )
Rs(1:3,4:6) = -Rs(1:3,4:6);
end
else
Rs_temp = zeros(3,3,2*numberSolutions);
index = 0;
for i=1:numberSolutions
%Check if there is any Nan
if ~isnan(Es(1,1,i))
[U,~,V] = svd(Es(:,:,i));
W = [0 -1 0; 1 0 0; 0 0 1];
index = index + 1;
Rs_temp( :,:, index ) = U * W * V';
if(det(Rs_temp( :,:, index )) < 0)
Rs_temp( :,:, index ) = -Rs_temp( :,:, index );
end
index = index + 1;
Rs_temp( :,:, index ) = U * W' * V';
if(det(Rs_temp( :,:, index )) < 0)
Rs_temp( :,:, index ) = -Rs_temp( :,:, index );
end
end
end
Rs = Rs_temp(:,:,1:index);
end
end