This page describes the format of trajectory files (.log) and information files (.info) provided on this site. This section includes only the format description. Please refer to other pages on this site and to our paper for the methods that were used to compute the camera trajectories.
Trajectory File (.log) Format
Every five lines are an item. The first line contains three numbers which store metadata and the other four lines make up the homogeneous transformation matrix.
In a typical camera pose trajectory file, the third number of the metadata is the frame number of the corresponding depth image (starting from 1) and the transformation matrix $\mathbf{p}$ maps a point $\mathbf{p}$ from its local coordinates (in homogeneous form) to the world coordinates $\mathbf{p}_{g}$: $$ \mathbf{p}_{g} = \mathbf{T}\mathbf{p}. $$ A .log file can contain information other than a camera pose trajectory. It must follow the general guideline of three number metadata plus a 4-by-4 transformation matrix. Please refer to specific instruction documents.
An example .log file is shown as follows:
0 0 1
1.0000000000 0.0000000000 0.0000000000 2.0000000000
0.0000000000 1.0000000000 0.0000000000 2.0000000000
0.0000000000 0.0000000000 1.0000000000 -0.3000000000
0.0000000000 0.0000000000 0.0000000000 1.0000000000
1 1 2
0.9999880000 0.0000308668 0.0049181000 1.9996200000
-0.0000884184 0.9999320000 0.0117022000 1.9770400000
-0.0049174000 -0.0117024000 0.9999190000 -0.3004860000
0.0000000000 0.0000000000 0.0000000000 1.0000000000
2 2 3
0.9999540000 -0.0000789780 0.0096394000 1.9993500000
-0.0001493510 0.9997200000 0.0236841000 1.9535300000
-0.0096385700 -0.0236844000 0.9996730000 -0.3015860000
0.0000000000 0.0000000000 0.0000000000 1.0000000000
Information File (.info) Format
The information file serves as an auxiliary file associated with a trajectory file. It contains the information (covariance) matrix of each transformation matrix. Thus it is composed of seven line items: first line is the metadata consistent with the .log file, and the other six lines make up a 6-by-6 information matrix.
An example .info file is shown as follows:
0 1 57
3305.00000000 0.00000000 0.00000000 0.00000000 10048.00680351 -13111.08558345
0.00000000 3305.00000000 0.00000000 -10048.00680351 0.00000000 13467.54784298
0.00000000 0.00000000 3305.00000000 13111.08558345 -13467.54784298 0.00000000
0.00000000 -10048.00680351 13111.08558345 85619.24609934 -53227.51496519 -42081.87222505
10048.00680351 0.00000000 -13467.54784298 -53227.51496519 91373.14395271 -39340.36625245
-13111.08558345 13467.54784298 0.00000000 -42081.87222505 -39340.36625245 114053.35097477
1 2 57
2723.00000000 0.00000000 0.00000000 0.00000000 7450.75675333 -11479.79212451
0.00000000 2723.00000000 0.00000000 -7450.75675333 0.00000000 10411.36079502
0.00000000 0.00000000 2723.00000000 11479.79212451 -10411.36079502 0.00000000
0.00000000 -7450.75675333 11479.79212451 70902.88919243 -43832.77854578 -28509.12099426
7450.75675333 0.00000000 -10411.36079502 -43832.77854578 63983.70568603 -31163.86104472
-11479.79212451 10411.36079502 0.00000000 -28509.12099426 -31163.86104472 93193.89366898
Matlab Code to Parse Files
Source: https://github.com/qianyizh/ElasticReconstruction/tree/master/Matlab_Toolbox/Core
The following code parses .log files. The code to parse .info files is similar.
function [ traj ] = mrLoadLog( filename )
fid = fopen( filename );
k = 1;
x = fscanf( fid, '%d', [1 3] );
while ( size( x, 2 ) == 3 )
m = fscanf( fid, '%f', [4 4] );
traj( k ) = struct( 'info', x, 'trans', m' );
k = k + 1;
x = fscanf( fid, '%d', [1 3] );
end
fclose( fid );
disp( [ num2str( size( traj, 2 ) ), ' frames have been read.' ] );
end
function mrWriteLog( traj, filename )
fid = fopen( filename, 'w' );
for i = 1 : size( traj, 2 )
mrWriteLogStruct( fid, traj( i ).info, traj( i ).trans );
end
fclose( fid );
disp( [ num2str( size( traj, 2 ) ), ' frames have been written.' ] );
end
function mrWriteLogStruct( fid, x, m )
fprintf( fid, '%d\t%d\t%d\n', x(1), x(2), x(3) );
fprintf( fid, '%.10f\t%.10f\t%.10f\t%.10f\n', m(1,1), m(1,2), m(1,3), m(1,4) );
fprintf( fid, '%.10f\t%.10f\t%.10f\t%.10f\n', m(2,1), m(2,2), m(2,3), m(2,4) );
fprintf( fid, '%.10f\t%.10f\t%.10f\t%.10f\n', m(3,1), m(3,2), m(3,3), m(3,4) );
fprintf( fid, '%.10f\t%.10f\t%.10f\t%.10f\n', m(4,1), m(4,2), m(4,3), m(4,4) );
end
Python Code to Parse Files
The following code parses .log files. The code to parse .info files is similar.
import numpy as np
import numpy.linalg
class CameraPose:
def __init__(self, meta, mat):
self.metadata = meta
self.pose = mat
def __str__(self):
return 'Metadata : ' + ' '.join(map(str, self.metadata)) + '\n' + \
"Pose : " + "\n" + np.array_str(self.pose)
def read_trajectory(filename):
traj = []
with open(filename, 'r') as f:
metastr = f.readline();
while metastr:
metadata = map(int, metastr.split())
mat = np.zeros(shape = (4, 4))
for i in range(4):
matstr = f.readline();
mat[i, :] = np.fromstring(matstr, dtype = float, sep=' \t')
traj.append(CameraPose(metadata, mat))
metastr = f.readline()
return traj
def write_trajectory(traj, filename):
with open(filename, 'w') as f:
for x in traj:
p = x.pose.tolist()
f.write(' '.join(map(str, x.metadata)) + '\n')
f.write('\n'.join(' '.join(map('{0:.12f}'.format, p[i])) for i in range(4)))
f.write('\n')
C++ Code to Parse Files
Source: https://github.com/qianyizh/ElasticReconstruction/blob/master/BuildCorrespondence/Helper.h
The following code parses .log files. The code to parse .info files is similar.
#pragma once
#include < vector >
#include < fstream >
#include < Eigen/Core >
typedef std::pair< int, int > IntPair;
struct FramedTransformation {
int id1_;
int id2_;
int frame_;
Eigen::Matrix4d transformation_;
FramedTransformation( int id1, int id2, int f, Eigen::Matrix4d t )
: id1_( id1 ), id2_( id2 ), frame_( f ), transformation_( t )
{}
};
struct RGBDTrajectory {
std::vector< FramedTransformation > data_;
int index_;
void LoadFromFile( std::string filename ) {
data_.clear();
index_ = 0;
int id1, id2, frame;
Eigen::Matrix4d trans;
FILE * f = fopen( filename.c_str(), "r" );
if ( f != NULL ) {
char buffer[1024];
while ( fgets( buffer, 1024, f ) != NULL ) {
if ( strlen( buffer ) > 0 && buffer[ 0 ] != '#' ) {
sscanf( buffer, "%d %d %d", &id1, &id2, &frame);
fgets( buffer, 1024, f );
sscanf( buffer, "%lf %lf %lf %lf", &trans(0,0), &trans(0,1), &trans(0,2), &trans(0,3) );
fgets( buffer, 1024, f );
sscanf( buffer, "%lf %lf %lf %lf", &trans(1,0), &trans(1,1), &trans(1,2), &trans(1,3) );
fgets( buffer, 1024, f );
sscanf( buffer, "%lf %lf %lf %lf", &trans(2,0), &trans(2,1), &trans(2,2), &trans(2,3) );
fgets( buffer, 1024, f );
sscanf( buffer, "%lf %lf %lf %lf", &trans(3,0), &trans(3,1), &trans(3,2), &trans(3,3) );
data_.push_back( FramedTransformation( id1, id2, frame, trans ) );
}
}
fclose( f );
}
}
void SaveToFile( std::string filename ) {
FILE * f = fopen( filename.c_str(), "w" );
for ( int i = 0; i < ( int )data_.size(); i++ ) {
Eigen::Matrix4d & trans = data_[ i ].transformation_;
fprintf( f, "%d\t%d\t%d\n", data_[ i ].id1_, data_[ i ].id2_, data_[ i ].frame_ );
fprintf( f, "%.8f %.8f %.8f %.8f\n", trans(0,0), trans(0,1), trans(0,2), trans(0,3) );
fprintf( f, "%.8f %.8f %.8f %.8f\n", trans(1,0), trans(1,1), trans(1,2), trans(1,3) );
fprintf( f, "%.8f %.8f %.8f %.8f\n", trans(2,0), trans(2,1), trans(2,2), trans(2,3) );
fprintf( f, "%.8f %.8f %.8f %.8f\n", trans(3,0), trans(3,1), trans(3,2), trans(3,3) );
}
fclose( f );
}
};