Beispiel #1
0
def get_average_point_color(track: SfmTrack,
                            images: List[Image]) -> Tuple[int, int, int]:
    """
    Args:
        track: 3d point/landmark and its corresponding 2d measurements in various cameras
        images: list of all images for this scene

    Returns:
        r: red color intensity, in range [0,255]
        g: green color intensity, in range [0,255]
        b: blue color intensity, in range [0,255]
    """
    rgb_measurements = []
    for k in range(track.number_measurements()):

        # process each measurement
        i, uv_measured = track.measurement(k)

        u, v = np.round(uv_measured).astype(np.int32)
        # ensure round did not push us out of bounds
        u = np.clip(u, 0, images[i].width - 1)
        v = np.clip(v, 0, images[i].height - 1)
        rgb_measurements += [images[i].value_array[v, u]]

    r, g, b = np.array(rgb_measurements).mean(axis=0).astype(np.uint8)
    return r, g, b
Beispiel #2
0
def compute_track_reprojection_errors(
        track_camera_dict: Dict[int, PinholeCameraCal3Bundler],
        track: SfmTrack) -> Tuple[np.ndarray, float]:
    """Compute reprojection errors for measurements in the tracks.

    Args:
        track_camera_dict: Dict of cameras, with camera indices as keys.
        track: 3d point/landmark and its corresponding 2d measurements in various cameras

    Returns:
        reprojection errors for each measurement (measured in pixels).
        avg_track_reproj_error: average reprojection error of all meausurements in track.
    """
    errors = []
    for k in range(track.numberMeasurements()):

        # process each measurement
        i, uv_measured = track.measurement(k)

        # get the camera associated with the measurement
        camera = track_camera_dict[i]
        # Project to camera
        uv_reprojected, success_flag = camera.projectSafe(track.point3())
        # Projection error in camera
        if success_flag:
            errors.append(np.linalg.norm(uv_measured - uv_reprojected))
        else:
            # failure in projection
            errors.append(np.nan)

    errors = np.array(errors)
    avg_track_reproj_error = np.nan if np.isnan(errors).all() else np.nanmean(
        errors)
    return errors, avg_track_reproj_error
Beispiel #3
0
    def add_track(self, track: SfmTrack) -> bool:
        """Add a track, after checking if all the cameras in the track are already added.

        Args:
            track: track to add.

        Returns:
            Flag indicating the success of adding operation.
        """
        # check if all cameras are already added
        for j in range(track.number_measurements()):
            i, _ = track.measurement(j)

            if i not in self._cameras:
                return False

        self._tracks.append(track)
        return True
Beispiel #4
0
class TestSfmData(GtsamTestCase):
    """Tests for SfmData and SfmTrack modules."""
    def setUp(self):
        """Initialize SfmData and SfmTrack"""
        self.data = SfmData()
        # initialize SfmTrack with 3D point
        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 = Point2(12.6, 82)

        # translating point uv_i1 along X-axis
        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(Point3(0., 0., 0.),
                                             self.tracks.point3())

    def test_data(self):
        """Test functions in SfmData"""
        # Create new track with 3 measurements
        i1, i2, i3 = 3, 5, 6
        uv_i1 = Point2(21.23, 45.64)

        # translating along X-axis
        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 = 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):
        """ Check that we can successfully read a bundler file and create a 
            factor graph from it
        """
        # The structure where we will save the SfM data
        filename = gtsam.findExampleDataFile("Balbianello.out")
        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