Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/wrap sfm data #569

Merged
merged 12 commits into from
Nov 9, 2020
8 changes: 8 additions & 0 deletions gtsam/gtsam.i
Original file line number Diff line number Diff line change
Expand Up @@ -2759,21 +2759,29 @@ virtual class EssentialMatrixFactor : gtsam::NoiseModelFactor {
};

#include <gtsam/slam/dataset.h>

class SfmTrack {
SfmTrack();
Point3 point3() const;
size_t number_measurements() const;
void set_point3(gtsam::Point3& p_);
swarrier246 marked this conversation as resolved.
Show resolved Hide resolved
pair<size_t, gtsam::Point2> measurement(size_t idx) const;
pair<size_t, size_t> siftIndex(size_t idx) const;
void add_measurement(const pair<size_t, gtsam::Point2>& m);
};

class SfmData {
SfmData();
size_t number_cameras() const;
size_t number_tracks() const;
gtsam::PinholeCamera<gtsam::Cal3Bundler> camera(size_t idx) const;
gtsam::SfmTrack track(size_t idx) const;
void add_track(const gtsam::SfmTrack& t) ;
void add_camera(const gtsam::SfmCamera& cam);
};

gtsam::SfmData readBal(string filename);
bool writeBAL(string filename, gtsam::SfmData& data);
swarrier246 marked this conversation as resolved.
Show resolved Hide resolved
gtsam::Values initialCamerasEstimate(const gtsam::SfmData& db);
gtsam::Values initialCamerasAndPointsEstimate(const gtsam::SfmData& db);

Expand Down
21 changes: 20 additions & 1 deletion gtsam/slam/dataset.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ GTSAM_EXPORT GraphAndValues load3D(const std::string& filename);
/// A measurement with its camera index
typedef std::pair<size_t, Point2> SfmMeasurement;

/// SfmTrack
/// Sift index for SfmTrack
typedef std::pair<size_t, size_t> SiftIndex;

/// Define the structure for the 3D points
Expand All @@ -221,10 +221,15 @@ struct SfmTrack {
float r, g, b; ///< RGB color of the 3D point
std::vector<SfmMeasurement> measurements; ///< The 2D image projections (id,(u,v))
std::vector<SiftIndex> siftIndices;

/// Total number of measurements in this track
size_t number_measurements() const {
return measurements.size();
}
/// Set 3D point
void set_point3(const Point3& p_){
swarrier246 marked this conversation as resolved.
Show resolved Hide resolved
p = p_;
}
/// Get the measurement (camera index, Point2) at pose index `idx`
SfmMeasurement measurement(size_t idx) const {
return measurements[idx];
Expand All @@ -233,11 +238,17 @@ struct SfmTrack {
SiftIndex siftIndex(size_t idx) const {
return siftIndices[idx];
}
/// Get 3D point
swarrier246 marked this conversation as resolved.
Show resolved Hide resolved
Point3 point3() const {
return p;
}
/// Add measurement to track
void add_measurement(const pair<size_t, gtsam::Point2>& m) {
measurements.push_back(m);
swarrier246 marked this conversation as resolved.
Show resolved Hide resolved
}
};


/// Define the structure for the camera poses
typedef PinholeCamera<Cal3Bundler> SfmCamera;

Expand All @@ -260,6 +271,14 @@ struct SfmData {
SfmTrack track(size_t idx) const {
return tracks[idx];
}
/// Add a track to SfmData
void add_track(const SfmTrack& t) {
tracks.push_back(t);
}
/// Add a camera to SfmData
void add_camera(const SfmCamera& cam){
cameras.push_back(cam);
}
};

/**
Expand Down
2 changes: 1 addition & 1 deletion python/gtsam/preamble.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ PYBIND11_MAKE_OPAQUE(std::vector<gtsam::Point2, Eigen::aligned_allocator<gtsam::
PYBIND11_MAKE_OPAQUE(std::vector<gtsam::Pose3>);
PYBIND11_MAKE_OPAQUE(std::vector<boost::shared_ptr<gtsam::BetweenFactor<gtsam::Pose3> > >);
PYBIND11_MAKE_OPAQUE(std::vector<boost::shared_ptr<gtsam::BetweenFactor<gtsam::Pose2> > >);
PYBIND11_MAKE_OPAQUE(std::vector<gtsam::IndexPair>);
PYBIND11_MAKE_OPAQUE(std::vector<gtsam::IndexPair>);
swarrier246 marked this conversation as resolved.
Show resolved Hide resolved
81 changes: 81 additions & 0 deletions python/gtsam/tests/test_SfmData.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"""
GTSAM Copyright 2010-2019, Georgia Tech Research Corporation,
Atlanta, Georgia 30332-0415
All Rights Reserved

See LICENSE for the license information

Unit tests for testing dataset access.
Author: Frank Dellaert (Python: Sushmita Warrier)
swarrier246 marked this conversation as resolved.
Show resolved Hide resolved
"""
# pylint: disable=invalid-name, no-name-in-module, no-member

from __future__ import print_function

import unittest

import numpy as np

import gtsam
#from gtsam import SfmCamera
swarrier246 marked this conversation as resolved.
Show resolved Hide resolved
from gtsam.utils.test_case import GtsamTestCase
swarrier246 marked this conversation as resolved.
Show resolved Hide resolved


class TestSfmData(GtsamTestCase):
"""Tests for SfmData and SfmTrack modules."""

def setUp(self):
"""Initialize SfmData and SfmTrack"""
self.data = gtsam.SfmData()
self.tracks = gtsam.SfmTrack()

def test_tracks(self):
"""Test functions in SfmTrack"""
# measurement is of format (camera_idx, imgPoint)
# create arbitrary camera indices for two cameras
i1, i2 = 4,5
# create arbitrary image measurements for cameras i1 and i2
uv_i1 = gtsam.Point2(12.6, 82)
# translating point uv_i1 along X-axis
uv_i2 = gtsam.Point2(24.88, 82)
m_i1 = (i1, uv_i1)
m_i2 = (i2, uv_i2)
# add measurements to the track
self.tracks.add_measurement(m_i1)
self.tracks.add_measurement(m_i2)
# Number of measurements in the track is 2
self.assertEqual(self.tracks.number_measurements(), 2)
# camera_idx in the first measurement of the track corresponds to i1
self.assertEqual(self.tracks.measurement(0)[0], i1)
# Set arbitrary 3D point corresponding to the track
self.tracks.set_point3(gtsam.Point3(2.5, 3.3, 1.2))
np.testing.assert_array_almost_equal(
gtsam.Point3(2.5,3.3,1.2),
self.tracks.point3()
)


def test_data(self):
"""Test functions in SfmData"""
#cam1 = gtsam.SfmCamera(1500, 1200, 0, 640, 480)
swarrier246 marked this conversation as resolved.
Show resolved Hide resolved
# Create new track with 3 measurements
track2 = gtsam.SfmTrack()
i1, i2, i3 = 3,5,6
uv_i1 = gtsam.Point2(21.23, 45.64)
# translating along X-axis
uv_i2 = gtsam.Point2(45.7, 45.64)
uv_i3 = gtsam.Point2(68.35, 45.64)
m_i1, m_i2, m_i3 = (i1, uv_i1), (i2, uv_i2), (i3, uv_i3)
# add measurements to the track
track2.add_measurement(m_i1)
track2.add_measurement(m_i2)
track2.add_measurement(m_i3)
self.data.add_track(self.tracks)
self.data.add_track(track2)
# Number of tracks in SfmData is 2
self.assertEqual(self.data.number_tracks(), 2)
# camera idx of first measurement of second track corresponds to i1
self.assertEqual(self.data.track(1).measurement(0)[0], i1)
johnwlambert marked this conversation as resolved.
Show resolved Hide resolved

if __name__ == '__main__':
unittest.main()