Spaces:
Build error
Build error
function evaluate_poses_keyframe | |
opt = globals(); | |
% read class names | |
fid = fopen('classes.txt', 'r'); | |
C = textscan(fid, '%s'); | |
object_names = C{1}; | |
fclose(fid); | |
% load model points | |
num_objects = numel(object_names); | |
models = cell(num_objects, 1); | |
for i = 1:num_objects | |
filename = fullfile(opt.root, 'models', object_names{i}, 'points.xyz'); | |
disp(filename); | |
models{i} = load(filename); | |
end | |
% load the keyframe indexes | |
fid = fopen('keyframe.txt', 'r'); | |
C = textscan(fid, '%s'); | |
keyframes = C{1}; | |
fclose(fid); | |
% save results | |
distances_sys = zeros(100000, 5); | |
distances_non = zeros(100000, 5); | |
errors_rotation = zeros(100000, 5); | |
errors_translation = zeros(100000, 5); | |
results_seq_id = zeros(100000, 1); | |
results_frame_id = zeros(100000, 1); | |
results_object_id = zeros(100000, 1); | |
results_cls_id = zeros(100000, 1); | |
% for each image | |
count = 0; | |
for i = 1:numel(keyframes) | |
% parse keyframe name | |
name = keyframes{i}; | |
pos = strfind(name, '/'); | |
seq_id = str2double(name(1:pos-1)); | |
frame_id = str2double(name(pos+1:end)); | |
% load PoseCNN result | |
filename = sprintf('results_PoseCNN_RSS2018/%06d.mat', i - 1); | |
result = load(filename); | |
filename = sprintf('Densefusion_iterative_result/%04d.mat', i - 1); | |
result_my = load(filename); | |
filename = sprintf('Densefusion_wo_refine_result/%04d.mat', i - 1); | |
result_mygt = load(filename); | |
% load 3D coordinate regression result | |
filename = sprintf('results_3DCoordinate/%04d.mat', i - 1); | |
result_3DCoordinate = load(filename); | |
% load gt poses | |
filename = fullfile(opt.root, 'data', sprintf('%04d/%06d-meta.mat', seq_id, frame_id)); | |
disp(filename); | |
gt = load(filename); | |
% for each gt poses | |
for j = 1:numel(gt.cls_indexes) | |
count = count + 1; | |
cls_index = gt.cls_indexes(j); | |
RT_gt = gt.poses(:, :, j); | |
results_seq_id(count) = seq_id; | |
results_frame_id(count) = frame_id; | |
results_object_id(count) = j; | |
results_cls_id(count) = cls_index; | |
% network result | |
roi_index = find(result.rois(:, 2) == cls_index); | |
if isempty(roi_index) == 0 | |
RT = zeros(3, 4); | |
% pose from network | |
RT(1:3, 1:3) = quat2rotm(result_my.poses(roi_index, 1:4)); | |
RT(:, 4) = result_my.poses(roi_index, 5:7); | |
distances_sys(count, 1) = adi(RT, RT_gt, models{cls_index}'); | |
distances_non(count, 1) = add(RT, RT_gt, models{cls_index}'); | |
errors_rotation(count, 1) = re(RT(1:3, 1:3), RT_gt(1:3, 1:3)); | |
errors_translation(count, 1) = te(RT(:, 4), RT_gt(:, 4)); | |
% pose after ICP refinement | |
RT(1:3, 1:3) = quat2rotm(result.poses_icp(roi_index, 1:4)); | |
RT(:, 4) = result.poses_icp(roi_index, 5:7); | |
distances_sys(count, 2) = adi(RT, RT_gt, models{cls_index}'); | |
distances_non(count, 2) = add(RT, RT_gt, models{cls_index}'); | |
errors_rotation(count, 2) = re(RT(1:3, 1:3), RT_gt(1:3, 1:3)); | |
errors_translation(count, 2) = te(RT(:, 4), RT_gt(:, 4)); | |
% pose from multiview | |
RT(1:3, 1:3) = quat2rotm(result_mygt.poses(roi_index, 1:4)); | |
RT(:, 4) = result_mygt.poses(roi_index, 5:7); | |
distances_sys(count, 3) = adi(RT, RT_gt, models{cls_index}'); | |
distances_non(count, 3) = add(RT, RT_gt, models{cls_index}'); | |
errors_rotation(count, 3) = re(RT(1:3, 1:3), RT_gt(1:3, 1:3)); | |
errors_translation(count, 3) = te(RT(:, 4), RT_gt(:, 4)); | |
% | |
% % pose from multiview + ICP | |
% RT(1:3, 1:3) = quat2rotm(result.poses_multiview_icp(roi_index, 1:4)); | |
% RT(:, 4) = result.poses_multiview_icp(roi_index, 5:7); | |
% distances_sys(count, 4) = adi(RT, RT_gt, models{cls_index}'); | |
% distances_non(count, 4) = add(RT, RT_gt, models{cls_index}'); | |
% errors_rotation(count, 4) = re(RT(1:3, 1:3), RT_gt(1:3, 1:3)); | |
% errors_translation(count, 4) = te(RT(:, 4), RT_gt(:, 4)); | |
else | |
distances_sys(count, 1:4) = inf; | |
distances_non(count, 1:4) = inf; | |
errors_rotation(count, 1:4) = inf; | |
errors_translation(count, 1:4) = inf; | |
end | |
% 3D Coordinate regression result | |
roi_index = find(result_3DCoordinate.rois(:, 2) == cls_index); | |
if isempty(roi_index) == 0 | |
RT = zeros(3, 4); | |
RT(1:3, 1:3) = quat2rotm(result_3DCoordinate.poses(roi_index, 1:4)); | |
RT(:, 4) = result_3DCoordinate.poses(roi_index, 5:7); | |
distances_sys(count, 5) = adi(RT, RT_gt, models{cls_index}'); | |
distances_non(count, 5) = add(RT, RT_gt, models{cls_index}'); | |
errors_rotation(count, 5) = re(RT(1:3, 1:3), RT_gt(1:3, 1:3)); | |
errors_translation(count, 5) = te(RT(:, 4), RT_gt(:, 4)); | |
else | |
distances_sys(count, 5) = inf; | |
distances_non(count, 5) = inf; | |
errors_rotation(count, 5) = inf; | |
errors_translation(count, 5) = inf; | |
end | |
end | |
end | |
distances_sys = distances_sys(1:count, :); | |
distances_non = distances_non(1:count, :); | |
errors_rotation = errors_rotation(1:count, :); | |
errors_translation = errors_translation(1:count, :); | |
results_seq_id = results_seq_id(1:count); | |
results_frame_id = results_frame_id(1:count); | |
results_object_id = results_object_id(1:count, :); | |
results_cls_id = results_cls_id(1:count, :); | |
save('results_keyframe.mat', 'distances_sys', 'distances_non', 'errors_rotation', 'errors_translation',... | |
'results_seq_id', 'results_frame_id', 'results_object_id', 'results_cls_id'); | |
function pts_new = transform_pts_Rt(pts, RT) | |
% """ | |
% Applies a rigid transformation to 3D points. | |
% | |
% :param pts: nx3 ndarray with 3D points. | |
% :param R: 3x3 rotation matrix. | |
% :param t: 3x1 translation vector. | |
% :return: nx3 ndarray with transformed 3D points. | |
% """ | |
n = size(pts, 2); | |
pts_new = RT * [pts; ones(1, n)]; | |
function error = add(RT_est, RT_gt, pts) | |
% """ | |
% Average Distance of Model Points for objects with no indistinguishable views | |
% - by Hinterstoisser et al. (ACCV 2012). | |
% | |
% :param R_est, t_est: Estimated pose (3x3 rot. matrix and 3x1 trans. vector). | |
% :param R_gt, t_gt: GT pose (3x3 rot. matrix and 3x1 trans. vector). | |
% :param model: Object model given by a dictionary where item 'pts' | |
% is nx3 ndarray with 3D model points. | |
% :return: Error of pose_est w.r.t. pose_gt. | |
% """ | |
pts_est = transform_pts_Rt(pts, RT_est); | |
pts_gt = transform_pts_Rt(pts, RT_gt); | |
diff = pts_est - pts_gt; | |
error = mean(sqrt(sum(diff.^2, 1))); | |
function error = adi(RT_est, RT_gt, pts) | |
% """ | |
% Average Distance of Model Points for objects with indistinguishable views | |
% - by Hinterstoisser et al. (ACCV 2012). | |
% | |
% :param R_est, t_est: Estimated pose (3x3 rot. matrix and 3x1 trans. vector). | |
% :param R_gt, t_gt: GT pose (3x3 rot. matrix and 3x1 trans. vector). | |
% :param model: Object model given by a dictionary where item 'pts' | |
% is nx3 ndarray with 3D model points. | |
% :return: Error of pose_est w.r.t. pose_gt. | |
% """ | |
pts_est = transform_pts_Rt(pts, RT_est); | |
pts_gt = transform_pts_Rt(pts, RT_gt); | |
% Calculate distances to the nearest neighbors from pts_gt to pts_est | |
MdlKDT = KDTreeSearcher(pts_est'); | |
[~, D] = knnsearch(MdlKDT, pts_gt'); | |
error = mean(D); | |
function error = re(R_est, R_gt) | |
% """ | |
% Rotational Error. | |
% | |
% :param R_est: Rotational element of the estimated pose (3x1 vector). | |
% :param R_gt: Rotational element of the ground truth pose (3x1 vector). | |
% :return: Error of t_est w.r.t. t_gt. | |
% """ | |
error_cos = 0.5 * (trace(R_est * inv(R_gt)) - 1.0); | |
error_cos = min(1.0, max(-1.0, error_cos)); | |
error = acos(error_cos); | |
error = 180.0 * error / pi; | |
function error = te(t_est, t_gt) | |
% """ | |
% Translational Error. | |
% | |
% :param t_est: Translation element of the estimated pose (3x1 vector). | |
% :param t_gt: Translation element of the ground truth pose (3x1 vector). | |
% :return: Error of t_est w.r.t. t_gt. | |
% """ | |
error = norm(t_gt - t_est); |