예제 #1
0
    def test_simple_trial_run_generated(self):
        sequence_folder, left_path, right_path = ndds_loader.find_files(
            NDDS_SEQUENCE)
        camera_intrinsics = ndds_loader.read_camera_intrinsics(
            left_path / '_camera_settings.json')
        max_img_id = ndds_loader.find_max_img_id(
            lambda idx: left_path / ndds_loader.IMG_TEMPLATE.format(idx))
        with (NDDS_SEQUENCE / 'timestamps.json').open('r') as fp:
            timestamps = json.load(fp)

        subject = LibVisOMonoSystem(
            matcher_nms_n=10,
            matcher_nms_tau=66,
            matcher_match_binsize=50,
            matcher_match_radius=245,
            matcher_match_disp_tolerance=2,
            matcher_outlier_disp_tolerance=5,
            matcher_outlier_flow_tolerance=2,
            matcher_multi_stage=False,
            matcher_half_resolution=False,
            matcher_refinement=MatcherRefinement.SUBPIXEL,
            bucketing_max_features=6,
            bucketing_bucket_width=136,
            bucketing_bucket_height=102,
            height=1.0,
            pitch=0.0,
            ransac_iters=439,
            inlier_threshold=4.921875,
            motion_threshold=609.375)
        subject.set_camera_intrinsics(camera_intrinsics, 0.1)

        subject.start_trial(ImageSequenceType.SEQUENTIAL, seed=0)
        image_group = 'test'
        with image_manager.get().get_group(image_group, allow_write=True):
            for img_idx in range(max_img_id + 1):
                pixels = image_utils.read_colour(
                    left_path / ndds_loader.IMG_TEMPLATE.format(img_idx))
                image = Image(
                    _id=bson.ObjectId(),
                    pixels=pixels,
                    image_group=image_group,
                    metadata=imeta.ImageMetadata(camera_pose=Transform()))
                subject.process_image(image, timestamps[img_idx])
        result = subject.finish_trial()

        self.assertIsInstance(result, SLAMTrialResult)
        self.assertEqual(subject, result.system)
        self.assertTrue(result.success)
        self.assertFalse(result.has_scale)
        self.assertIsNotNone(result.run_time)
        self.assertEqual(max_img_id + 1, len(result.results))
예제 #2
0
    def test_is_different_with_changed_seed(self):
        # Actually run the system using mocked images
        num_frames = 50
        max_time = 50
        speed = 0.1
        image_builder = DemoImageBuilder(
            mode=ImageMode.MONOCULAR,
            width=640, height=480, num_stars=150,
            length=max_time * speed, speed=speed,
            close_ratio=0.6, min_size=10, max_size=100
        )

        subject = LibVisOMonoSystem(motion_threshold=1000)
        subject.set_camera_intrinsics(image_builder.get_camera_intrinsics(), max_time / num_frames)
        subject.set_stereo_offset(image_builder.get_stereo_offset())

        subject.start_trial(ImageSequenceType.SEQUENTIAL, seed=0)
        for idx in range(num_frames):
            time = max_time * idx / num_frames
            image = image_builder.create_frame(time)
            subject.process_image(image, time)
        result1 = subject.finish_trial()

        subject.start_trial(ImageSequenceType.SEQUENTIAL, seed=2)
        for idx in range(num_frames):
            time = max_time * idx / num_frames
            image = image_builder.create_frame(time)
            subject.process_image(image, time)
        result2 = subject.finish_trial()

        self.assertEqual(len(result1.results), len(result2.results))
        different_tracking = 0
        loc_diff = np.zeros(3)
        quat_diff = np.zeros(4)
        for frame_result_1, frame_result_2 in zip(result1.results, result2.results):
            self.assertEqual(frame_result_1.timestamp, frame_result_2.timestamp)
            if frame_result_1.tracking_state != frame_result_2.tracking_state:
                different_tracking += 1
            elif frame_result_1.estimated_motion is not None and frame_result_2.estimated_motion is not None:
                motion1 = frame_result_1.estimated_motion
                motion2 = frame_result_2.estimated_motion

                loc_diff += np.abs(motion1.location - motion2.location)
                quat_diff += np.abs(motion1.rotation_quat(True) - motion2.rotation_quat(True))
        if different_tracking <= 0:
            # If the tracking is the same, make sure the estimates are at least different
            self.assertNotNPClose(loc_diff, np.zeros(3), rtol=0, atol=1e-10)
            self.assertNotNPClose(quat_diff, np.zeros(4), rtol=0, atol=1e-10)
예제 #3
0
    def test_is_consistent_with_fixed_seed(self):
        # Actually run the system using mocked images
        num_frames = 20
        max_time = 50
        speed = 0.1
        image_builder = DemoImageBuilder(
            mode=ImageMode.MONOCULAR,
            width=640, height=480, num_stars=150,
            length=max_time * speed, speed=speed,
            close_ratio=0.6, min_size=10, max_size=100
        )

        subject = LibVisOMonoSystem(motion_threshold=1000)
        subject.set_camera_intrinsics(image_builder.get_camera_intrinsics(), max_time / num_frames)

        subject.start_trial(ImageSequenceType.SEQUENTIAL, seed=0)
        for idx in range(num_frames):
            time = max_time * idx / num_frames
            image = image_builder.create_frame(time)
            subject.process_image(image, time)
        result1 = subject.finish_trial()

        subject.start_trial(ImageSequenceType.SEQUENTIAL, seed=0)
        for idx in range(num_frames):
            time = max_time * idx / num_frames
            image = image_builder.create_frame(time)
            subject.process_image(image, time)
        result2 = subject.finish_trial()

        has_any_estimate = False
        self.assertEqual(len(result1.results), len(result2.results))
        for frame_result_1, frame_result_2 in zip(result1.results, result2.results):
            self.assertEqual(frame_result_1.timestamp, frame_result_2.timestamp)
            self.assertEqual(frame_result_1.tracking_state, frame_result_2.tracking_state)
            if frame_result_1.estimated_motion is None or frame_result_2.estimated_motion is None:
                self.assertEqual(frame_result_1.estimated_motion, frame_result_2.estimated_motion)
            else:
                has_any_estimate = True
                motion1 = frame_result_1.estimated_motion
                motion2 = frame_result_2.estimated_motion

                loc_diff = motion1.location - motion2.location
                self.assertNPClose(loc_diff, np.zeros(3), rtol=0, atol=1e-14)
                quat_diff = motion1.rotation_quat(True) - motion2.rotation_quat(True)
                self.assertNPClose(quat_diff, np.zeros(4), rtol=0, atol=1e-14)
        self.assertTrue(has_any_estimate)
예제 #4
0
    def test_result_saves(self):
        # Make an image collection with some number of images
        images = []
        image_builder = DemoImageBuilder(mode=ImageMode.MONOCULAR, width=160, height=120)
        num_images = 10
        for time in range(num_images):
            image = image_builder.create_frame(time / num_images)
            image.save()
            images.append(image)
        image_collection = ImageCollection(
            images=images,
            timestamps=list(range(len(images))),
            sequence_type=ImageSequenceType.SEQUENTIAL
        )
        image_collection.save()

        subject = LibVisOMonoSystem()
        subject.save()

        # Actually run the system using mocked images
        subject.set_camera_intrinsics(image_builder.get_camera_intrinsics(), 1 / 10)
        subject.start_trial(ImageSequenceType.SEQUENTIAL)
        for time, image in enumerate(images):
            subject.process_image(image, time)
        result = subject.finish_trial()
        self.assertIsInstance(result, SLAMTrialResult)
        self.assertEqual(len(image_collection), len(result.results))
        result.image_source = image_collection
        result.save()

        # Load all the entities
        all_entities = list(SLAMTrialResult.objects.all())
        self.assertGreaterEqual(len(all_entities), 1)
        self.assertEqual(all_entities[0], result)
        all_entities[0].delete()

        SLAMTrialResult._mongometa.collection.drop()
        ImageCollection._mongometa.collection.drop()
        Image._mongometa.collection.drop()
예제 #5
0
    def test_can_run_on_colour_images(self):
        # Actually run the system using mocked images
        num_frames = 50
        max_time = 50
        speed = 0.1
        image_builder = DemoImageBuilder(
            mode=ImageMode.MONOCULAR,
            width=640, height=480, num_stars=150,
            length=max_time * speed, speed=speed,
            close_ratio=0.6, min_size=1, max_size=50, colour=True
        )

        subject = LibVisOMonoSystem(motion_threshold=1000)
        subject.set_camera_intrinsics(image_builder.get_camera_intrinsics(), max_time / num_frames)

        subject.start_trial(ImageSequenceType.SEQUENTIAL, seed=0)
        for idx in range(num_frames):
            time = max_time * idx / num_frames
            image = image_builder.create_frame(time)
            subject.process_image(image, time)
        result = subject.finish_trial()

        self.assertIsInstance(result, SLAMTrialResult)
        self.assertEqual(subject, result.system)
        self.assertTrue(result.success)
        self.assertFalse(result.has_scale)
        self.assertIsNotNone(result.run_time)
        self.assertEqual({
            'seed': 0,
            'in_fx': image_builder.focal_length,
            'in_fy': image_builder.focal_length,
            'in_cu': image_builder.width / 2,
            'in_cv': image_builder.height / 2,
            'in_width': image_builder.width,
            'in_height': image_builder.height
        }, result.settings)
        self.assertEqual(num_frames, len(result.results))

        has_been_found = False
        has_been_lost = False
        for idx, frame_result in enumerate(result.results):
            self.assertEqual(max_time * idx / num_frames, frame_result.timestamp)
            self.assertIsNotNone(frame_result.pose)
            self.assertIsNotNone(frame_result.motion)

            # If we're lost, our tracking state should depend of if we've been lost before
            is_first_frame = False
            if frame_result.tracking_state != TrackingState.OK:
                if has_been_found:
                    has_been_lost = True
                    self.assertEqual(frame_result.tracking_state, TrackingState.LOST)
                else:
                    self.assertEqual(frame_result.tracking_state, TrackingState.NOT_INITIALIZED)
            elif has_been_found is False:
                is_first_frame = True
                has_been_found = True

            # Motion should be none when we are lost, and on the first found frame
            if is_first_frame or frame_result.tracking_state != TrackingState.OK:
                self.assertIsNone(frame_result.estimated_motion)
            else:
                self.assertIsNotNone(frame_result.estimated_motion)

            # Estimates will be none until we get a successful estimate, or after it has lost
            if not has_been_found or has_been_lost:
                self.assertIsNone(frame_result.estimated_pose)
            else:
                self.assertIsNotNone(frame_result.estimated_pose)
        self.assertTrue(has_been_found)