def setUp(self): with zipfile.ZipFile("./Ressources/MidAir.zip", "r") as zip_ref: zip_ref.extractall("./Ressources") self.processor = MidAirDataPreprocessor("./Ressources/MidAir") self.processor.clean() data_segmenter = MidAirDataSegmenter("./Ressources/MidAir/Kite_test") data_segmenter.segment((4, ), 0)
def setUp(self): with zipfile.ZipFile("./Ressources/MidAir.zip", "r") as zip_ref: zip_ref.extractall("./Ressources") self.processor = MidAirDataPreprocessor( "./Ressources/MidAir/Kite_test/") self.processor.clean() data_segmenter = MidAirDataSegmenter("./Ressources/MidAir/Kite_test/") # segment so that 1 trajectory equals 1 segment data_segmenter.segment() self.sensor_record = h5py.File( "./Ressources/MidAir/Kite_test/cloudy/sensor_records.hdf5", "r+")
def setUp(self): with zipfile.ZipFile("./Ressources/MidAir.zip", "r") as zip_ref: zip_ref.extractall("./Ressources") self.processor = MidAirDataPreprocessor("./Ressources/MidAir") self.processor.clean() data_segmenter = MidAirDataSegmenter("./Ressources/MidAir/Kite_test") data_segmenter.segment((4, ), 0) self.dataset: MidAirImageSequenceDataset = MidAirImageSequenceDataset( "./Ressources/MidAir/Kite_test", new_size=(512, 512), img_mean=(1, 1, 1)) self.second_segment: Segment = self.dataset._get_segment(1)
def test_givenMidAirDataset_whenCallingComputingMeanStd_shouldCreateFileWithValidValues( self): processor = MidAirDataPreprocessor("./Ressources/MidAir_mean_std_test") processor.compute_dataset_image_mean_std() mean = pickle.load( open("./Ressources/MidAir_mean_std_test/Means.pkl", "rb")) std = pickle.load( open("./Ressources/MidAir_mean_std_test/StandardDevs.pkl", "rb")) self.assertSequenceEqual(mean["mean_np"], [1.0, 1.0, 1.0]) self.assertSequenceEqual( mean["mean_tensor"], [0.003921568859368563, 0.003921568859368563, 0.003921568859368563]) self.assertSequenceEqual(std["std_np"], [0.0, 0.0, 0.0]) self.assertSequenceEqual(std["std_tensor"], [0.0, 0.0, 0.0])
def test_givenMidAirDataset_whenCallingComputingMeanStdMinus0point5_shouldCreateFileWithValidValues( self): processor = MidAirDataPreprocessor("./Ressources/MidAir_mean_std_test") processor.compute_dataset_image_mean_std(True) mean = pickle.load( open("./Ressources/MidAir_mean_std_test/Means.pkl", "rb")) std = pickle.load( open("./Ressources/MidAir_mean_std_test/StandardDevs.pkl", "rb")) self.assertSequenceEqual(mean["mean_np"], [1.0, 1.0, 1.0]) self.assertSequenceEqual( mean["mean_tensor"], [-0.4960784316062927, -0.4960784316062927, -0.4960784316062927]) self.assertSequenceEqual(std["std_np"], [0.0, 0.0, 0.0]) self.assertSequenceEqual(std["std_tensor"], [0.0, 0.0, 0.0])
class TestSegmentMapper(TestCase): def setUp(self): with zipfile.ZipFile("./Ressources/MidAir.zip", "r") as zip_ref: zip_ref.extractall("./Ressources") self.processor = MidAirDataPreprocessor( "./Ressources/MidAir/Kite_test/") self.processor.clean() data_segmenter = MidAirDataSegmenter("./Ressources/MidAir/Kite_test/") # segment so that 1 trajectory equals 1 segment data_segmenter.segment() self.sensor_record = h5py.File( "./Ressources/MidAir/Kite_test/cloudy/sensor_records.hdf5", "r+") def tearDown(self): shutil.rmtree("./Ressources/MidAir") def test_given_sensor_record_when_no_trajectories_specified_should_map_all_segments( self): mapper = SegmentMapper() segments = mapper.map_all( "./Ressources/MidAir_segment_mapper_tests/MidAir/Kite_test/cloudy/", self.sensor_record) self.assertEqual(len(segments), 5) def test_given_sensor_record_when_trajectories_specified_should_map_segments_of_specified_trajectories_only( self): mapper = SegmentMapper() segments = mapper.map_all( "./Ressources/MidAir_segment_mapper_tests/MidAir/Kite_test/cloudy/", self.sensor_record, ["trajectory_3000", "trajectory_3001"]) self.assertEqual(len(segments), 2) for segments in segments: self.assertTrue( segments.trajectory in ["trajectory_3000", "trajectory_3001"])
class TestMidAirImageSequenceDatasetDeepVO(TestCase): def setUp(self): with zipfile.ZipFile("./Ressources/MidAir.zip", "r") as zip_ref: zip_ref.extractall("./Ressources") self.processor = MidAirDataPreprocessor("./Ressources/MidAir") self.processor.clean() data_segmenter = MidAirDataSegmenter("./Ressources/MidAir/Kite_test") data_segmenter.segment((4, ), 0) def tearDown(self): shutil.rmtree("./Ressources/MidAir") def test_givenDataset_whenCallingItem_ShouldReturnTheTupleOfTheCorrespondingSegment( self): dataset = MidAirImageSequenceDatasetEulerDifferences( "./Ressources/MidAir/Kite_test", new_size=(512, 512), img_mean=[1, 1, 1], img_std=[1, 1, 1], trajectories=["trajectory_3000"]) first_segment = dataset.__getitem__(1) # First item should be the segment's images as image tensors self.assertEqual(len(first_segment[0]), 4) # verify the image size and its type for image in first_segment[0]: self.assertTrue(isinstance(image, torch.FloatTensor)) self.assertEqual(image.shape, (3, 512, 512)) # Third item should be the image's pose self.assertEqual(first_segment[1].shape, (3, 6)) def test_givenDataset_whenCallingItem_ShouldReturnTheTupleWithProperAttitude( self): dataset = MidAirImageSequenceDatasetEulerDifferences( "./Ressources/MidAir/Kite_test", new_size=(512, 512), img_mean=[1, 1, 1], img_std=[1, 1, 1], trajectories=["trajectory_3000"]) relative_attitude = dataset.__getitem__(1)[1][:, :3] with dataset.HDF5["./Ressources/MidAir/Kite_test/cloudy"] as hdf5: expected_attitude = hdf5["trajectory_3000"]["groundtruth"][ "attitude"][4:8] initial_rotation = Quaternion(expected_attitude[0]) relative_attitude = Geometry.tait_bryan_rotations_to_quaternions( relative_attitude) actual_attitudes = Geometry.assemble_delta_quaternion_rotations( relative_attitude) actual_attitudes = self._rotate_quaternions_to_world_frame( actual_attitudes) actual_attitudes = Geometry.reset_orientations_to_origin( initial_rotation, actual_attitudes) actual_attitudes = [att.elements for att in actual_attitudes] self.assertTrue(numpy.allclose(actual_attitudes, expected_attitude)) def test_givenDataset_whenCallingItem_ShouldReturnTheTupleWithProperPosition( self): dataset = MidAirImageSequenceDatasetEulerDifferences( "./Ressources/MidAir/Kite_test", new_size=(512, 512), img_mean=[1, 1, 1], img_std=[1, 1, 1], trajectories=["trajectory_3000"]) with dataset.HDF5["./Ressources/MidAir/Kite_test/cloudy"] as hdf5: expected_position = hdf5["trajectory_3000"]["groundtruth"][ "position"][4:8] initial_rotation = Quaternion( hdf5["trajectory_3000"]["groundtruth"]["attitude"][4]) initial_position = expected_position[0] #Reverse position differences actual_position_differences = dataset.__getitem__(1)[1][:, 3:].numpy() self.assertEqual(actual_position_differences.shape, (3, 3)) actual_positions = Geometry.assemble_delta_translations( actual_position_differences) actual_positions = self._rotate_camera_frame_to_world_frame( torch.Tensor(actual_positions)).numpy() #remap axis to original absolute frame actual_positions = Geometry.remap_position_axes( initial_rotation, actual_positions) actual_positions = Geometry.reset_positions_to_origin( initial_position, actual_positions) self.assertEqual(actual_positions.shape, (4, 3)) self.assertTrue(numpy.allclose(actual_positions, expected_position)) def _rotate_camera_frame_to_world_frame( self, position: torch.Tensor) -> torch.Tensor: return torch.mm( position, torch.Tensor(self._get_to_world_frame_rotation_matrix())) def _rotate_quaternions_to_world_frame(self, quatertions): # Rotate the i,j,k (x,y,z) component of the quaternion to the camera frame using the rotation matrix remapped_quaternions = [] for quaternion in quatertions: world_frame_quat = numpy.append( quaternion.elements[:1], quaternion.elements[1:].dot( self._get_to_world_frame_rotation_matrix())) remapped_quaternions.append(Quaternion(world_frame_quat)) return remapped_quaternions def _get_to_world_frame_rotation_matrix(self) -> numpy.ndarray: """ Rotation matrix describing the tranformation to the world frame of midair (x: forward, y:right, z:down) from the camera frame (x: right, y:down, z:forward) @return: """ to_camera_frame_rotation_matrix = numpy.asarray([[0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [1.0, 0.0, 0.0]]) return to_camera_frame_rotation_matrix
class TestSegment(TestCase): def setUp(self): with zipfile.ZipFile("./Ressources/MidAir.zip", "r") as zip_ref: zip_ref.extractall("./Ressources") self.processor = MidAirDataPreprocessor("./Ressources/MidAir") self.processor.clean() data_segmenter = MidAirDataSegmenter("./Ressources/MidAir/Kite_test") data_segmenter.segment((4, ), 0) self.dataset: MidAirImageSequenceDataset = MidAirImageSequenceDataset( "./Ressources/MidAir/Kite_test", new_size=(512, 512), img_mean=(1, 1, 1)) self.second_segment: Segment = self.dataset._get_segment(1) def tearDown(self): shutil.rmtree("./Ressources/MidAir") def test_givenDataset_whenCallingGetPosition_shouldReturnProperPosition( self): with self.dataset.HDF5["./Ressources/MidAir/Kite_test/cloudy"] as hdf5: expected_position = hdf5["trajectory_3000"]["groundtruth"][ "position"][4:8] initial_rotation = Quaternion( hdf5["trajectory_3000"]["groundtruth"]["attitude"][4]) initial_position = expected_position[0] actual_positions_camera_frame = self.second_segment.get_positions( ).numpy() self.assertEqual(actual_positions_camera_frame.shape, (4, 3)) numpy.testing.assert_array_equal(actual_positions_camera_frame[0], numpy.asarray([0.0, 0.0, 0.0])) #remap axis to original absolute frame actual_position = self._rotate_camera_frame_to_world_frame( torch.Tensor(actual_positions_camera_frame)).numpy() for i, pos in enumerate(actual_positions_camera_frame): #assert that the positions were switch to the KITTI camera coordinate systen numpy.testing.assert_array_equal(actual_position[i], pos[[2, 0, 1]]) actual_position = Geometry.remap_position_axes(initial_rotation, actual_position) actual_position = Geometry.reset_positions_to_origin( initial_position, actual_position) self.assertTrue(numpy.allclose(actual_position, expected_position)) def test_givenDataset_whenCallingGetPositionDifferences_shouldReturnProperPositionDifferences( self): with self.dataset.HDF5["./Ressources/MidAir/Kite_test/cloudy"] as hdf5: expected_position = hdf5["trajectory_3000"]["groundtruth"][ "position"][4:8] initial_rotation = Quaternion( hdf5["trajectory_3000"]["groundtruth"]["attitude"][4]) initial_position = expected_position[0] #Reverse position differences actual_position_differences = self.second_segment.get_position_differences( ).numpy() self.assertEqual(actual_position_differences.shape, (3, 3)) actual_positions_camera_frame = Geometry.assemble_delta_translations( actual_position_differences) #remap axis to original absolute frame actual_positions = self._rotate_camera_frame_to_world_frame( torch.Tensor(actual_positions_camera_frame)).numpy() for i, pos in enumerate(actual_positions_camera_frame): #assert that the positions were switch to the KITTI camera coordinate systen numpy.testing.assert_array_equal(actual_positions[i], pos[[2, 0, 1]]) actual_positions = Geometry.remap_position_axes( initial_rotation, actual_positions) actual_positions = Geometry.reset_positions_to_origin( initial_position, actual_positions) self.assertEqual(actual_positions.shape, (4, 3)) self.assertTrue(numpy.allclose(actual_positions, expected_position)) def test_givenDataset_whenCallingGetAttitudes_shouldReturnProperAttitude( self): with self.dataset.HDF5["./Ressources/MidAir/Kite_test/cloudy"] as hdf5: expected_attitude = hdf5["trajectory_3000"]["groundtruth"][ "attitude"][4:8] initial_attitude = expected_attitude[0] actual_attitude = self.second_segment.get_attitudes() self.assertEqual(len(actual_attitude), 4) self.assertEqual( None, numpy.testing.assert_array_almost_equal( actual_attitude[0].elements, numpy.asarray([1.0, 0.0, 0.0, 0.0]))) actual_attitude_camera_frame = Geometry.quaternion_elements_to_quaternions( actual_attitude) actual_attitude = self._rotate_quaternions_to_world_frame( actual_attitude_camera_frame) for i, quat in enumerate(actual_attitude_camera_frame): imaginaries = quat.elements[1:] #assert that the quaternions were switch to the KITTI camera coordinate systen numpy.testing.assert_array_equal(actual_attitude[i].elements[1:], imaginaries[[2, 0, 1]]) actual_attitude = Geometry.reset_orientations_to_origin( Quaternion(initial_attitude), actual_attitude) self.assertTrue( numpy.allclose( numpy.asarray([att.elements for att in actual_attitude]), expected_attitude)) def test_givenDataset_whenCallingGetAttitudeDifferences_shouldReturnProperAttitudeDifference( self): with self.dataset.HDF5["./Ressources/MidAir/Kite_test/cloudy"] as hdf5: expected_attitude = hdf5["trajectory_3000"]["groundtruth"][ "attitude"][4:8] initial_attitude = expected_attitude[0] actual_attitude_differences = self.second_segment.get_attitude_differences( ) self.assertEqual(len(actual_attitude_differences), 3) self.assertFalse( numpy.allclose(actual_attitude_differences[0].elements, numpy.asarray([1.0, 0.0, 0.0, 0.0]))) actual_attitude = Geometry.assemble_delta_quaternion_rotations( actual_attitude_differences) self.assertEqual(len(actual_attitude), 4) self.assertEqual( None, numpy.testing.assert_array_almost_equal( actual_attitude[0].elements, numpy.asarray([1.0, 0.0, 0.0, 0.0]))) actual_attitude_camera_frame = Geometry.quaternion_elements_to_quaternions( actual_attitude) actual_attitude = self._rotate_quaternions_to_world_frame( actual_attitude_camera_frame) for i, quat in enumerate(actual_attitude_camera_frame): imaginaries = quat.elements[1:] #assert that the quaternions were switch to the KITTI camera coordinate systen numpy.testing.assert_array_equal(actual_attitude[i].elements[1:], imaginaries[[2, 0, 1]]) actual_attitude = Geometry.reset_orientations_to_origin( Quaternion(initial_attitude), actual_attitude) self.assertTrue( numpy.allclose( numpy.asarray([att.elements for att in actual_attitude]), expected_attitude)) def test_rotate_quaternion_to_camera_frame(self): pose_deg = numpy.array([1, 1.5, 1.2]) # Degrees to radians pose_quat = Quaternion( Rotation.from_euler("ZYX", pose_deg).as_quat()[[3, 0, 1, 2]]) segment = Segment(root="", trajectory="", camera_view="", start_frame_index=0, segment_length=1, hdf5=None) remapped_quat = segment._rotate_quaternion_to_camera_frame(pose_quat) pose_deg_unmapped_ZYX = Rotation.from_quat( pose_quat.elements[[1, 2, 3, 0]]).as_euler("ZYX") pose_deg_unmapped_YXZ = Rotation.from_quat( pose_quat.elements[[1, 2, 3, 0]]).as_euler("YXZ") pose_deg_remapped_YXZ = Rotation.from_quat( remapped_quat.elements[[1, 2, 3, 0]]).as_euler("YXZ") self.assertNotEqual(pose_deg_unmapped_ZYX[0], pose_deg_unmapped_YXZ[0]) self.assertNotEqual(pose_deg_unmapped_ZYX[1], pose_deg_unmapped_YXZ[1]) self.assertNotEqual(pose_deg_unmapped_ZYX[2], pose_deg_unmapped_YXZ[2]) numpy.testing.assert_almost_equal(pose_deg_unmapped_ZYX, pose_deg) # Remaped quaternion should have yaw-pitch-roll axis as YXZ respectively numpy.testing.assert_array_equal(pose_deg_unmapped_ZYX, pose_deg_remapped_YXZ) def test_remap_position_axis_to_camera_frame(self): pose = numpy.array([[1, 1.5, 1.2], [1, 1.5, 1.2]]) segment = Segment(root="", trajectory="", camera_view="", start_frame_index=0, segment_length=1, hdf5=None) remapped_pose = segment._rotate_world_frame_to_camera_frame( torch.Tensor(pose)).numpy() numpy.testing.assert_almost_equal(remapped_pose, [[1.5, 1.2, 1], [1.5, 1.2, 1]]) def _rotate_quaternions_to_world_frame(self, quatertions): # Rotate the i,j,k (x,y,z) component of the quaternion to the camera frame using the rotation matrix remapped_quaternions = [] for quaternion in quatertions: world_frame_quat = numpy.append( quaternion.elements[:1], quaternion.elements[1:].dot( self._get_to_world_frame_rotation_matrix())) remapped_quaternions.append(Quaternion(world_frame_quat)) return remapped_quaternions def _rotate_camera_frame_to_world_frame( self, position: torch.Tensor) -> torch.Tensor: return torch.mm( position, torch.Tensor(self._get_to_world_frame_rotation_matrix())) def _get_to_world_frame_rotation_matrix(self) -> numpy.ndarray: """ Rotation matrix describing the tranformation to the world frame of midair (x: forward, y:right, z:down) from the camera frame (x: right, y:down, z:forward) @return: """ to_camera_frame_rotation_matrix = numpy.asarray([[0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [1.0, 0.0, 0.0]]) return to_camera_frame_rotation_matrix
class TestMidAirImageSequenceDataset(TestCase): def setUp(self): with zipfile.ZipFile("./Ressources/MidAir.zip", "r") as zip_ref: zip_ref.extractall("./Ressources") self.processor = MidAirDataPreprocessor("./Ressources/MidAir") self.processor.clean() data_segmenter = MidAirDataSegmenter("./Ressources/MidAir/Kite_test") data_segmenter.segment((4, ), 0) def tearDown(self): shutil.rmtree("./Ressources/MidAir") def test_givenDataset_whenCallingLen_ShouldReturnTotalNumberOfSegmentsInTheDatasetPath( self): dataset = MidAirImageSequenceDataset("./Ressources/MidAir/Kite_test", new_size=(512, 512)) total_number_of_segments = 0 with dataset.HDF5["./Ressources/MidAir/Kite_test/cloudy"] as hdf5: for trajectory in hdf5: total_number_of_segments += len( hdf5[trajectory]["trajectory_segments"]) self.assertEqual(total_number_of_segments, dataset.__len__()) def test_givenSpecificTrajectories_whenCallingLen_ShouldReturnTotalNumberOfSegmentsInTheTrajectoryPath( self): dataset = MidAirImageSequenceDataset("./Ressources/MidAir/Kite_test", new_size=(512, 512), trajectories=["trajectory_3001"]) with dataset.HDF5["./Ressources/MidAir/Kite_test/cloudy"] as hdf5: total_number_of_segments = len( hdf5["trajectory_3001"]["trajectory_segments"]) self.assertEqual(total_number_of_segments, dataset.__len__()) def test_givenDataset_whenCallingItem_ShouldReturnTheTupleOfTheCorrespondingSegment( self): dataset = MidAirImageSequenceDataset("./Ressources/MidAir/Kite_test", new_size=(512, 512), img_mean=[1, 1, 1], img_std=[1, 1, 1]) first_segment, img_sequence = dataset.__getitem__(0) # First item should be the segment self.assertTrue(isinstance(first_segment, Segment)) # Second item should be the segment's images as image tensors self.assertEqual(len(img_sequence), 4) # verify the image size and its type for image in img_sequence: self.assertTrue(isinstance(image, torch.FloatTensor)) self.assertEqual(image.shape, (3, 512, 512)) def test_givenDataset_when_no_trajectories_specified_should_map_all_segments( self): # re-segment so that 1 trajectory equals 1 segment data_segmenter = MidAirDataSegmenter("./Ressources/MidAir/Kite_test") data_segmenter.segment() dataset = MidAirImageSequenceDataset("./Ressources/MidAir/Kite_test", new_size=(512, 512)) self.assertEqual(dataset.__len__(), 5) def test_given_sensor_record_when_trajectories_specified_should_map_segments_of_specified_trajectories_only( self): # re-segment so that 1 trajectory equals 1 segment data_segmenter = MidAirDataSegmenter("./Ressources/MidAir/Kite_test") data_segmenter.segment() dataset = MidAirImageSequenceDataset( "./Ressources/MidAir/Kite_test", new_size=(512, 512), trajectories=["trajectory_3000", "trajectory_3001"]) self.assertEqual(dataset.__len__(), 2) for i in range(0, dataset.__len__()): self.assertTrue( dataset._get_segment(i).trajectory in ["trajectory_3000", "trajectory_3001"])
def setUp(self): with zipfile.ZipFile("./Ressources/MidAir.zip", "r") as zip_ref: zip_ref.extractall("./Ressources") self.processor = MidAirDataPreprocessor("./Ressources/MidAir") self.processor.clean()
class TestMidAirDataSegmenter(TestCase): def setUp(self): with zipfile.ZipFile("./Ressources/MidAir.zip", "r") as zip_ref: zip_ref.extractall("./Ressources") self.processor = MidAirDataPreprocessor("./Ressources/MidAir") self.processor.clean() def tearDown(self): shutil.rmtree("./Ressources/MidAir") def test_segment_givenSingleSegmentLength_shouldProduceFixedLengthSegments( self): data_segmenter = MidAirDataSegmenter("./Ressources/MidAir/Kite_test") data_segmenter.segment((4, ), 0) sensor_records = h5py.File( "./Ressources/MidAir/Kite_test/cloudy/sensor_records.hdf5", "r+") for trajectory in sensor_records: dataframe = pd.DataFrame( sensor_records[trajectory]["trajectory_segments"], columns=["sequence_length", "start_frame_index"]) expected_length = len( list( range( 0, data_segmenter._get_trajectory_length( sensor_records[trajectory]) - 4, 4))) self.assertEqual(len(dataframe), expected_length) expected_start_Frame_index = 0 for i, row in dataframe.iterrows(): self.assertEqual(row["sequence_length"], 4) self.assertEqual(row["start_frame_index"], expected_start_Frame_index) expected_start_Frame_index += 4 def test_segment_when_resegmenting_should_overwrite_segment(self): data_segmenter = MidAirDataSegmenter("./Ressources/MidAir/Kite_test") # first segmentation data_segmenter.segment((4, ), 0) # second segmentation data_segmenter.segment((6, ), 0) sensor_records = h5py.File( "./Ressources/MidAir/Kite_test/cloudy/sensor_records.hdf5", "r+") for trajectory in sensor_records: dataframe = pd.DataFrame( sensor_records[trajectory]["trajectory_segments"], columns=["sequence_length", "start_frame_index"]) expected_length = len( list( range( 0, data_segmenter._get_trajectory_length( sensor_records[trajectory]) - 6, 6))) self.assertEqual(len(dataframe), expected_length) expected_start_Frame_index = 0 for i, row in dataframe.iterrows(): self.assertEqual(row["sequence_length"], 6) self.assertEqual(row["start_frame_index"], expected_start_Frame_index) expected_start_Frame_index += 6 def test_segment_givenNoneSegmentLength_shouldSegmentWillBeTrajectory( self): data_segmenter = MidAirDataSegmenter("./Ressources/MidAir/Kite_test") data_segmenter.segment(None) sensor_records = h5py.File( "./Ressources/MidAir/Kite_test/cloudy/sensor_records.hdf5", "r+") for trajectory in sensor_records: dataframe = pd.DataFrame( sensor_records[trajectory]["trajectory_segments"], columns=["sequence_length", "start_frame_index"]) expected_length = 1 self.assertEqual(len(dataframe), expected_length) for i, row in dataframe.iterrows(): self.assertEqual( row["sequence_length"], data_segmenter._get_trajectory_length( sensor_records[trajectory])) self.assertEqual(row["start_frame_index"], 0) def test_segment_givenSingleSegmentLengthAndOverlap_shouldProduceFixedLengthOverlappingSegments( self): data_segmenter = MidAirDataSegmenter("./Ressources/MidAir/Kite_test") data_segmenter.segment((4, ), 1) sensor_records = h5py.File( "./Ressources/MidAir/Kite_test/cloudy/sensor_records.hdf5", "r+") for trajectory in sensor_records: dataframe = pd.DataFrame( sensor_records[trajectory]["trajectory_segments"], columns=["sequence_length", "start_frame_index"]) expected_length = len( list( range( 0, data_segmenter._get_trajectory_length( sensor_records[trajectory]) - 4, 3))) self.assertEqual(len(dataframe), expected_length) expected_start_Frame_index = 0 for i, row in dataframe.iterrows(): self.assertEqual(row["sequence_length"], 4) self.assertEqual(row["start_frame_index"], expected_start_Frame_index) expected_start_Frame_index += 3 def test_segment_givenRangeSegmentLength_shouldProduceVariableLengthOverlappingSegments( self): data_segmenter = MidAirDataSegmenter("./Ressources/MidAir/Kite_test") data_segmenter.segment((2, 4), 1) sensor_records = h5py.File( "./Ressources/MidAir/Kite_test/cloudy/sensor_records.hdf5", "r+") for trajectory in sensor_records: dataframe = pd.DataFrame( sensor_records[trajectory]["trajectory_segments"], columns=["sequence_length", "start_frame_index"]) self.assertTrue(3 in dataframe["sequence_length"]) self.assertTrue(4 in dataframe["sequence_length"]) self.assertTrue(2 in dataframe["sequence_length"]) expected_start_Frame_index = 0 for i, row in dataframe.iterrows(): self.assertTrue(row["sequence_length"] <= 4 or row["sequence_length"] >= 2) self.assertEqual(row["start_frame_index"], expected_start_Frame_index) expected_start_Frame_index += row["sequence_length"] - 1 def test_segment_givenRangeSegmentLength_shouldProduceVariableLengthSegments( self): data_segmenter = MidAirDataSegmenter("./Ressources/MidAir/Kite_test") data_segmenter.segment((2, 4), 0) sensor_records = h5py.File( "./Ressources/MidAir/Kite_test/cloudy/sensor_records.hdf5", "r+") for trajectory in sensor_records: dataframe = pd.DataFrame( sensor_records[trajectory]["trajectory_segments"], columns=["sequence_length", "start_frame_index"]) self.assertTrue(3 in dataframe["sequence_length"]) self.assertTrue(4 in dataframe["sequence_length"]) self.assertTrue(2 in dataframe["sequence_length"]) expected_start_Frame_index = 0 for i, row in dataframe.iterrows(): self.assertTrue(row["sequence_length"] <= 4 or row["sequence_length"] >= 2) self.assertEqual(row["start_frame_index"], expected_start_Frame_index) expected_start_Frame_index += row["sequence_length"]
class MidAirDataPreprocessorTest(unittest.TestCase): def setUp(self): with zipfile.ZipFile("./Ressources/MidAir.zip", "r") as zip_ref: zip_ref.extractall("./Ressources") self.processor = MidAirDataPreprocessor("./Ressources/MidAir") def tearDown(self): shutil.rmtree("./Ressources/MidAir") def test_given_midAirDataset_whenCallingClean_ShouldExtractFramesAndDeleteArchive( self): self.processor.clean() self.assertTrue( os.path.exists( "./Ressources/MidAir/Kite_test/cloudy/color_left/trajectory_3000/000000.JPEG" )) self.assertFalse( os.path.exists( "./Ressources/MidAir/Kite_test/cloudy/color_left/trajectory_3000/frames.zip" )) def test_given_midAirDataset_whenCallingClean_ShouldExtractSensorRecordAndDeleteArchive( self): self.processor.clean() self.assertTrue( os.path.exists( "./Ressources/MidAir/Kite_test/cloudy/sensor_records.hdf5")) self.assertTrue( os.path.exists( "./Ressources/MidAir/Kite_test/cloudy/sensor_records.zip")) def test_givenMidAirDataset_whenCallingClean_shouldOnlyKeepPositionAndAttitude( self): self.processor.clean() sensor_records = h5py.File( "./Ressources/MidAir/Kite_test/cloudy/sensor_records.hdf5", "r+") self.assertFalse( "velocity" in sensor_records["trajectory_3000"]["groundtruth"]) self.assertFalse( "acceleration" in sensor_records["trajectory_3000"]["groundtruth"]) self.assertFalse("angular_velocity" in sensor_records["trajectory_3000"]["groundtruth"]) self.assertTrue( "attitude" in sensor_records["trajectory_3000"]["groundtruth"]) self.assertTrue( "position" in sensor_records["trajectory_3000"]["groundtruth"]) def test_givenMidAirDataset_whenCallingClean_shouldReduceGroundTruthFrom100HzTo25Hz( self): sensor_records_untouched = h5py.File( "./Ressources/MidAir/Kite_test/cloudy/sensor_records_untouched.hdf5", "r+") self.processor.clean() sensor_records = h5py.File( "./Ressources/MidAir/Kite_test/cloudy/sensor_records.hdf5", "r+") self.assertEqual( sensor_records["trajectory_3000"]["groundtruth"]["position"].len(), sensor_records["trajectory_3000"]["camera_data"] ["color_left"].len()) self.assertEqual( sensor_records["trajectory_3000"]["groundtruth"]["attitude"].len(), sensor_records["trajectory_3000"]["camera_data"] ["color_left"].len()) # select every frame at every start of a second hundredHz1Sec_pos = sensor_records_untouched["trajectory_3000"][ "groundtruth"]["position"][0::100] twentyfiveHz1Sec_pos = sensor_records["trajectory_3000"][ "groundtruth"]["position"][0::25] hundredHz1Sec_att = sensor_records_untouched["trajectory_3000"][ "groundtruth"]["attitude"][0::100] twentyfiveHz1Sec_att = sensor_records["trajectory_3000"][ "groundtruth"]["attitude"][0::25] self.assertTrue( numpy.array_equal(hundredHz1Sec_pos, twentyfiveHz1Sec_pos)) self.assertTrue( numpy.array_equal(hundredHz1Sec_att, twentyfiveHz1Sec_att)) def test_givenMidAirDataset_whenCallingComputingMeanStd_shouldCreateFileWithValidValues( self): processor = MidAirDataPreprocessor("./Ressources/MidAir_mean_std_test") processor.compute_dataset_image_mean_std() mean = pickle.load( open("./Ressources/MidAir_mean_std_test/Means.pkl", "rb")) std = pickle.load( open("./Ressources/MidAir_mean_std_test/StandardDevs.pkl", "rb")) self.assertSequenceEqual(mean["mean_np"], [1.0, 1.0, 1.0]) self.assertSequenceEqual( mean["mean_tensor"], [0.003921568859368563, 0.003921568859368563, 0.003921568859368563]) self.assertSequenceEqual(std["std_np"], [0.0, 0.0, 0.0]) self.assertSequenceEqual(std["std_tensor"], [0.0, 0.0, 0.0]) def test_givenMidAirDataset_whenCallingComputingMeanStdMinus0point5_shouldCreateFileWithValidValues( self): processor = MidAirDataPreprocessor("./Ressources/MidAir_mean_std_test") processor.compute_dataset_image_mean_std(True) mean = pickle.load( open("./Ressources/MidAir_mean_std_test/Means.pkl", "rb")) std = pickle.load( open("./Ressources/MidAir_mean_std_test/StandardDevs.pkl", "rb")) self.assertSequenceEqual(mean["mean_np"], [1.0, 1.0, 1.0]) self.assertSequenceEqual( mean["mean_tensor"], [-0.4960784316062927, -0.4960784316062927, -0.4960784316062927]) self.assertSequenceEqual(std["std_np"], [0.0, 0.0, 0.0]) self.assertSequenceEqual(std["std_tensor"], [0.0, 0.0, 0.0])
from Datasets.KITTI import KITTIDataPreprocessor from Datasets.MidAir import MidAirDataPreprocessor from Parameters import Parameters if __name__ == '__main__': param = Parameters() if param.dataset is "MidAir" or param.dataset is "all": processor = MidAirDataPreprocessor(param.midair_path) print("Cleaning Midair dataset") processor.clean() print("Computing mean and std dev for the images of the MidAir dataset, this will take a while...") processor.compute_dataset_image_mean_std() if param.dataset is "KITTI" or param.dataset is "all": processor = KITTIDataPreprocessor(param.kitti_image_dir, param.kitti_pose_dir, param.kitti_path) print("Cleaning KITTI dataset") processor.clean() print("Computing mean and std dev for the images of the KITTI dataset, this will take a while...") processor.compute_dataset_image_mean_std()