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