Add to wrapper
							parent
							
								
									9dfe52d0b6
								
							
						
					
					
						commit
						5d6b8f445e
					
				| 
						 | 
				
			
			@ -31,15 +31,23 @@ class SfmTrack {
 | 
			
		|||
#include <gtsam/sfm/SfmData.h>
 | 
			
		||||
class SfmData {
 | 
			
		||||
  SfmData();
 | 
			
		||||
  gtsam::SfmData FromBundlerFile(string filename);
 | 
			
		||||
  gtsam::SfmData FromBalFile(string filename);
 | 
			
		||||
  static gtsam::SfmData FromBundlerFile(string filename);
 | 
			
		||||
  static gtsam::SfmData FromBalFile(string filename);
 | 
			
		||||
 | 
			
		||||
  size_t numberCameras() const;
 | 
			
		||||
  size_t numberTracks() const;
 | 
			
		||||
  gtsam::PinholeCamera<gtsam::Cal3Bundler> camera(size_t idx) const;
 | 
			
		||||
  gtsam::SfmTrack track(size_t idx) const;
 | 
			
		||||
  void addTrack(const gtsam::SfmTrack& t);
 | 
			
		||||
  void addCamera(const gtsam::SfmCamera& cam);
 | 
			
		||||
  size_t numberTracks() const;
 | 
			
		||||
  size_t numberCameras() const;
 | 
			
		||||
  gtsam::SfmTrack track(size_t idx) const;
 | 
			
		||||
  gtsam::PinholeCamera<gtsam::Cal3Bundler> camera(size_t idx) const;
 | 
			
		||||
 | 
			
		||||
  gtsam::NonlinearFactorGraph generalSfmFactors(
 | 
			
		||||
      const gtsam::SharedNoiseModel& model =
 | 
			
		||||
          gtsam::noiseModel::Isotropic::Sigma(2, 1.0)) const;
 | 
			
		||||
  gtsam::NonlinearFactorGraph sfmFactorGraph(
 | 
			
		||||
      const gtsam::SharedNoiseModel& model =
 | 
			
		||||
          gtsam::noiseModel::Isotropic::Sigma(2, 1.0),
 | 
			
		||||
      size_t fixedCamera = 0, size_t fixedPoint = 0) const;
 | 
			
		||||
 | 
			
		||||
  // enabling serialization functionality
 | 
			
		||||
  void serialize() const;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,7 +15,7 @@ import logging
 | 
			
		|||
import sys
 | 
			
		||||
 | 
			
		||||
import gtsam
 | 
			
		||||
from gtsam import (GeneralSFMFactorCal3Bundler,
 | 
			
		||||
from gtsam import (GeneralSFMFactorCal3Bundler, SfmData,
 | 
			
		||||
                   PriorFactorPinholeCameraCal3Bundler, PriorFactorPoint3)
 | 
			
		||||
from gtsam.symbol_shorthand import C, P  # type: ignore
 | 
			
		||||
from gtsam.utils import plot  # type: ignore
 | 
			
		||||
| 
						 | 
				
			
			@ -26,7 +26,7 @@ logging.basicConfig(stream=sys.stdout, level=logging.INFO)
 | 
			
		|||
DEFAULT_BAL_DATASET = "dubrovnik-3-7-pre"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def plot_scene(scene_data: gtsam.SfmData, result: gtsam.Values) -> None:
 | 
			
		||||
def plot_scene(scene_data: SfmData, result: gtsam.Values) -> None:
 | 
			
		||||
    """Plot the SFM results."""
 | 
			
		||||
    plot_vals = gtsam.Values()
 | 
			
		||||
    for cam_idx in range(scene_data.numberCameras()):
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +46,7 @@ def run(args: argparse.Namespace) -> None:
 | 
			
		|||
    input_file = args.input_file
 | 
			
		||||
 | 
			
		||||
    # Load the SfM data from file
 | 
			
		||||
    scene_data = gtsam.readBal(input_file)
 | 
			
		||||
    scene_data = SfmData.FromBalFile(input_file)
 | 
			
		||||
    logging.info("read %d tracks on %d cameras\n", scene_data.numberTracks(),
 | 
			
		||||
                 scene_data.numberCameras())
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,6 +17,7 @@ import unittest
 | 
			
		|||
import numpy as np
 | 
			
		||||
 | 
			
		||||
import gtsam
 | 
			
		||||
from gtsam import SfmData, SfmTrack, Point2, Point3
 | 
			
		||||
from gtsam.utils.test_case import GtsamTestCase
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -25,29 +26,34 @@ class TestSfmData(GtsamTestCase):
 | 
			
		|||
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        """Initialize SfmData and SfmTrack"""
 | 
			
		||||
        self.data = gtsam.SfmData()
 | 
			
		||||
        self.data = SfmData()
 | 
			
		||||
        # initialize SfmTrack with 3D point
 | 
			
		||||
        self.tracks = gtsam.SfmTrack()
 | 
			
		||||
        self.tracks = 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)
 | 
			
		||||
        uv_i1 = Point2(12.6, 82)
 | 
			
		||||
        
 | 
			
		||||
        # translating point uv_i1 along X-axis
 | 
			
		||||
        uv_i2 = gtsam.Point2(24.88, 82)
 | 
			
		||||
        uv_i2 = Point2(24.88, 82)
 | 
			
		||||
        
 | 
			
		||||
        # add measurements to the track
 | 
			
		||||
        self.tracks.addMeasurement(i1, uv_i1)
 | 
			
		||||
        self.tracks.addMeasurement(i2, uv_i2)
 | 
			
		||||
        
 | 
			
		||||
        # Number of measurements in the track is 2
 | 
			
		||||
        self.assertEqual(self.tracks.numberMeasurements(), 2)
 | 
			
		||||
        
 | 
			
		||||
        # camera_idx in the first measurement of the track corresponds to i1
 | 
			
		||||
        cam_idx, img_measurement = self.tracks.measurement(0)
 | 
			
		||||
        self.assertEqual(cam_idx, i1)
 | 
			
		||||
        np.testing.assert_array_almost_equal(
 | 
			
		||||
            gtsam.Point3(0.,0.,0.), 
 | 
			
		||||
            Point3(0.,0.,0.), 
 | 
			
		||||
            self.tracks.point3()
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -56,24 +62,58 @@ class TestSfmData(GtsamTestCase):
 | 
			
		|||
        """Test functions in SfmData"""
 | 
			
		||||
        # Create new track with 3 measurements
 | 
			
		||||
        i1, i2, i3 = 3,5,6
 | 
			
		||||
        uv_i1 = gtsam.Point2(21.23, 45.64)
 | 
			
		||||
        uv_i1 = 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)
 | 
			
		||||
        uv_i2 = Point2(45.7, 45.64)
 | 
			
		||||
        uv_i3 = Point2(68.35, 45.64)
 | 
			
		||||
        
 | 
			
		||||
        # add measurements and arbitrary point to the track
 | 
			
		||||
        measurements = [(i1, uv_i1), (i2, uv_i2), (i3, uv_i3)]
 | 
			
		||||
        pt = gtsam.Point3(1.0, 6.0, 2.0)
 | 
			
		||||
        track2 = gtsam.SfmTrack(pt)
 | 
			
		||||
        pt = Point3(1.0, 6.0, 2.0)
 | 
			
		||||
        track2 = SfmTrack(pt)
 | 
			
		||||
        track2.addMeasurement(i1, uv_i1)
 | 
			
		||||
        track2.addMeasurement(i2, uv_i2)
 | 
			
		||||
        track2.addMeasurement(i3, uv_i3)
 | 
			
		||||
        self.data.addTrack(self.tracks)
 | 
			
		||||
        self.data.addTrack(track2)
 | 
			
		||||
 | 
			
		||||
        # Number of tracks in SfmData is 2
 | 
			
		||||
        self.assertEqual(self.data.numberTracks(), 2)
 | 
			
		||||
        
 | 
			
		||||
        # camera idx of first measurement of second track corresponds to i1
 | 
			
		||||
        cam_idx, img_measurement = self.data.track(1).measurement(0)
 | 
			
		||||
        self.assertEqual(cam_idx, i1)
 | 
			
		||||
 | 
			
		||||
    def test_Balbianello(self):
 | 
			
		||||
        # The structure where we will save the SfM data
 | 
			
		||||
        filename = gtsam.findExampleDataFile("Balbianello")
 | 
			
		||||
        sfm_data = SfmData.FromBundlerFile(filename)
 | 
			
		||||
 | 
			
		||||
        # Check number of things
 | 
			
		||||
        self.assertEqual(5, sfm_data.numberCameras())
 | 
			
		||||
        self.assertEqual(544, sfm_data.numberTracks())
 | 
			
		||||
        track0 = sfm_data.track(0)
 | 
			
		||||
        self.assertEqual(3, track0.numberMeasurements())
 | 
			
		||||
 | 
			
		||||
        # Check projection of a given point
 | 
			
		||||
        self.assertEqual(0, track0.measurement(0)[0])
 | 
			
		||||
        camera0 = sfm_data.camera(0)
 | 
			
		||||
        expected = camera0.project(track0.point3())
 | 
			
		||||
        actual = track0.measurement(0)[1]
 | 
			
		||||
        self.gtsamAssertEquals(expected, actual, 1)
 | 
			
		||||
 | 
			
		||||
        # We share *one* noiseModel between all projection factors
 | 
			
		||||
        model = gtsam.noiseModel.Isotropic.Sigma(2, 1.0)  # one pixel in u and v
 | 
			
		||||
 | 
			
		||||
        # Convert to NonlinearFactorGraph
 | 
			
		||||
        graph = sfm_data.sfmFactorGraph(model)
 | 
			
		||||
        self.assertEqual(1419, graph.size())  # regression
 | 
			
		||||
 | 
			
		||||
        # Get initial estimate
 | 
			
		||||
        values = gtsam.initialCamerasAndPointsEstimate(sfm_data)
 | 
			
		||||
        self.assertEqual(549, values.size())  # regression
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    unittest.main()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue