diff options
-rw-r--r-- | src/argaze.test/ArGazeScene.py | 59 | ||||
-rw-r--r-- | src/argaze.test/ArScene.py | 59 | ||||
-rw-r--r-- | src/argaze/ArScene.py (renamed from src/argaze/ArGazeScene.py) | 22 | ||||
-rw-r--r-- | src/argaze/ArUcoMarkers/ArUcoScene.py | 172 | ||||
-rw-r--r-- | src/argaze/__init__.py | 2 | ||||
-rw-r--r-- | src/argaze/utils/tobii_segment_arscene_export.py (renamed from src/argaze/utils/tobii_segment_argaze_scene_export.py) | 36 |
6 files changed, 180 insertions, 170 deletions
diff --git a/src/argaze.test/ArGazeScene.py b/src/argaze.test/ArGazeScene.py deleted file mode 100644 index 4d0b3ae..0000000 --- a/src/argaze.test/ArGazeScene.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env python - -import unittest -import os - -from argaze import ArGazeScene - -import numpy - -class TestArGazeSceneClass(unittest.TestCase): - """Test ArGazeScene class.""" - - def test_from_json(self): - """Test ArGazeScene creation from json file.""" - - # Edit scene file path - current_directory = os.path.dirname(os.path.abspath(__file__)) - json_filepath = os.path.join(current_directory, 'utils/scene.json') - - # Load scene - argaze_scene = ArGazeScene.ArGazeScene.from_json(json_filepath) - - # Check scene meta data - self.assertEqual(argaze_scene.name, "TestScene") - self.assertEqual(argaze_scene.aruco_dictionary.name, "DICT_ARUCO_ORIGINAL") - self.assertEqual(argaze_scene.aruco_marker_size, 3.0) - - # Check ArUco camera - self.assertEqual(argaze_scene.aruco_camera.rms, 1.0) - self.assertIsNone(numpy.testing.assert_array_equal(argaze_scene.aruco_camera.dimensions, [1920, 1080])) - self.assertIsNone(numpy.testing.assert_array_equal(argaze_scene.aruco_camera.K, [[1.0, 0.0, 1.0], [0.0, 1.0, 1.0], [0.0, 0.0, 1.0]])) - self.assertIsNone(numpy.testing.assert_array_equal(argaze_scene.aruco_camera.D, [-1.0, -0.5, 0.0, 0.5, 1.0])) - - # Check ArUco tracker - self.assertEqual(argaze_scene.aruco_tracker.tracking_data.cornerRefinementMethod, 3) - self.assertEqual(argaze_scene.aruco_tracker.tracking_data.aprilTagQuadSigma, 2) - self.assertEqual(argaze_scene.aruco_tracker.tracking_data.aprilTagDeglitch, 1) - - # Check ArUco scene - self.assertEqual(argaze_scene.aruco_scene.angle_tolerance, 1.0) - self.assertEqual(argaze_scene.aruco_scene.distance_tolerance, 2.0) - self.assertEqual(len(argaze_scene.aruco_scene.places), 2) - - # Check ArUco scene places - self.assertIsNone(numpy.testing.assert_array_equal(argaze_scene.aruco_scene.places['A'].translation, [1, 0, 0])) - self.assertIsNone(numpy.testing.assert_array_equal(argaze_scene.aruco_scene.places['A'].rotation, [0, 0, 0])) - self.assertEqual(argaze_scene.aruco_scene.places['A'].marker.identifier, 0) - - self.assertIsNone(numpy.testing.assert_array_equal(argaze_scene.aruco_scene.places['B'].translation, [0, 1, 0])) - self.assertIsNone(numpy.testing.assert_array_equal(argaze_scene.aruco_scene.places['B'].rotation, [0, 90, 0])) - self.assertEqual(argaze_scene.aruco_scene.places['B'].marker.identifier, 1) - - # Check AOI scene - self.assertEqual(len(argaze_scene.aoi_scene.items()), 1) - self.assertEqual(argaze_scene.aoi_scene['Test'].size, 4) - -if __name__ == '__main__': - - unittest.main()
\ No newline at end of file diff --git a/src/argaze.test/ArScene.py b/src/argaze.test/ArScene.py new file mode 100644 index 0000000..cfb949b --- /dev/null +++ b/src/argaze.test/ArScene.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python + +import unittest +import os + +from argaze import ArScene + +import numpy + +class TestArSceneClass(unittest.TestCase): + """Test ArScene class.""" + + def test_from_json(self): + """Test ArScene creation from json file.""" + + # Edit scene file path + current_directory = os.path.dirname(os.path.abspath(__file__)) + json_filepath = os.path.join(current_directory, 'utils/scene.json') + + # Load scene + ar_scene = ArScene.ArScene.from_json(json_filepath) + + # Check scene meta data + self.assertEqual(ar_scene.name, "TestScene") + self.assertEqual(ar_scene.aruco_dictionary.name, "DICT_ARUCO_ORIGINAL") + self.assertEqual(ar_scene.aruco_marker_size, 3.0) + + # Check ArUco camera + self.assertEqual(ar_scene.aruco_camera.rms, 1.0) + self.assertIsNone(numpy.testing.assert_array_equal(ar_scene.aruco_camera.dimensions, [1920, 1080])) + self.assertIsNone(numpy.testing.assert_array_equal(ar_scene.aruco_camera.K, [[1.0, 0.0, 1.0], [0.0, 1.0, 1.0], [0.0, 0.0, 1.0]])) + self.assertIsNone(numpy.testing.assert_array_equal(ar_scene.aruco_camera.D, [-1.0, -0.5, 0.0, 0.5, 1.0])) + + # Check ArUco tracker + self.assertEqual(ar_scene.aruco_tracker.tracking_data.cornerRefinementMethod, 3) + self.assertEqual(ar_scene.aruco_tracker.tracking_data.aprilTagQuadSigma, 2) + self.assertEqual(ar_scene.aruco_tracker.tracking_data.aprilTagDeglitch, 1) + + # Check ArUco scene + self.assertEqual(ar_scene.aruco_scene.angle_tolerance, 1.0) + self.assertEqual(ar_scene.aruco_scene.distance_tolerance, 2.0) + self.assertEqual(len(ar_scene.aruco_scene.places), 2) + + # Check ArUco scene places + self.assertIsNone(numpy.testing.assert_array_equal(ar_scene.aruco_scene.places['A'].translation, [1, 0, 0])) + self.assertIsNone(numpy.testing.assert_array_equal(ar_scene.aruco_scene.places['A'].rotation, [0, 0, 0])) + self.assertEqual(ar_scene.aruco_scene.places['A'].marker.identifier, 0) + + self.assertIsNone(numpy.testing.assert_array_equal(ar_scene.aruco_scene.places['B'].translation, [0, 1, 0])) + self.assertIsNone(numpy.testing.assert_array_equal(ar_scene.aruco_scene.places['B'].rotation, [0, 90, 0])) + self.assertEqual(ar_scene.aruco_scene.places['B'].marker.identifier, 1) + + # Check AOI scene + self.assertEqual(len(ar_scene.aoi_scene.items()), 1) + self.assertEqual(ar_scene.aoi_scene['Test'].size, 4) + +if __name__ == '__main__': + + unittest.main()
\ No newline at end of file diff --git a/src/argaze/ArGazeScene.py b/src/argaze/ArScene.py index 0eb4ebc..0a88b0c 100644 --- a/src/argaze/ArGazeScene.py +++ b/src/argaze/ArScene.py @@ -10,11 +10,11 @@ from argaze.AreaOfInterest import * import numpy -ArGazeSceneType = TypeVar('ArGazeScene', bound="ArGazeScene") +ArSceneType = TypeVar('ArScene', bound="ArScene") # Type definition for type annotation convenience @dataclass -class ArGazeScene(): +class ArScene(): """Define an Augmented Reality environnement thanks to ArUco markers and project it onto incoming frames.""" name: str @@ -74,7 +74,7 @@ class ArGazeScene(): self.__dict__.update(kwargs) @classmethod - def from_json(self, json_filepath: str) -> ArGazeSceneType: + def from_json(self, json_filepath: str) -> ArSceneType: """Load ArGaze project from .json file.""" with open(json_filepath) as configuration_file: @@ -82,7 +82,7 @@ class ArGazeScene(): # Store current directory to allow relative path loading self.__current_directory = os.path.dirname(os.path.abspath(json_filepath)) - return ArGazeScene(**json.load(configuration_file)) + return ArScene(**json.load(configuration_file)) def __str__(self) -> str: """String display""" @@ -95,8 +95,8 @@ class ArGazeScene(): return output - def project(self, frame, valid_markers:int = 1, visual_hfov=0): - """Project ArGazeScene into frame.""" + def project(self, frame, consistent_markers_number:int = 1, visual_hfov=0): + """Project ArScene into frame.""" # Track markers with pose estimation and draw them self.aruco_tracker.track(frame) @@ -107,17 +107,17 @@ class ArGazeScene(): raise UserWarning('No marker detected') # Estimate set pose from tracked markers - tvec, rvec, success, validity, unvalid = self.aruco_scene.estimate_pose(self.aruco_tracker.tracked_markers) + tvec, rvec, success, consistent_markers, unconsistencies = self.aruco_scene.estimate_pose(self.aruco_tracker.tracked_markers) # When pose estimation fails, ignore AOI scene projection if not success: raise UserWarning('Pose estimation fails') - # Consider pose estimation only if it is validated by a given number of valid markers at least - elif validity >= valid_markers: + # Consider pose estimation only if theer is a given number of consistent markers at least + elif len(consistent_markers) >= consistent_markers_number: - # Clip AOI out of the horizontal visual field of view (optional) + # Clip AOI out of the visual horizontal field of view (optional) if visual_hfov > 0: # Transform scene into camera referential @@ -145,4 +145,4 @@ class ArGazeScene(): raise UserWarning('AOI projection is empty') - return aoi_scene_projection, unvalid + return aoi_scene_projection, unconsistencies diff --git a/src/argaze/ArUcoMarkers/ArUcoScene.py b/src/argaze/ArUcoMarkers/ArUcoScene.py index 857ebf4..b267102 100644 --- a/src/argaze/ArUcoMarkers/ArUcoScene.py +++ b/src/argaze/ArUcoMarkers/ArUcoScene.py @@ -77,7 +77,7 @@ class ArUcoScene(): self._translation = numpy.zeros(3) self._rotation = numpy.zeros(3) self._succeded = False - self._validity = 0 + self._consistent_markers = 0 # Process markers ids to speed up further calculations self.__identifier_cache = {} @@ -308,7 +308,7 @@ class ArUcoScene(): I = numpy.identity(3, dtype = R.dtype) return numpy.linalg.norm(I - numpy.dot(R.T, R)) < 1e-6 - def __normalise_place_pose(self, name, place, F): + def __normalise_marker_pose(self, name, place, F): # Transform place rotation into scene rotation vector R = self.__rotation_cache[name] @@ -328,73 +328,73 @@ class ArUcoScene(): return rvec, tvec def estimate_pose(self, tracked_markers) -> Tuple[numpy.array, numpy.array, bool, int, dict]: - """Estimate scene pose from tracked markers (cf ArUcoTracker.track()) + """Estimate scene pose from tracked markers (cf ArUcoTracker.track()) and validate its consistency according expected scene places. * **Returns:** - - translation vector - - rotation vector - - pose estimation success status - - the number of places used to estimate the pose as validity score - - dict of non valid distance and angle + - scene translation vector + - scene rotation vector + - scene pose estimation success status + - all tracked markers considered as consistent and used to estimate the pose + - dict of identified distance or angle unconsistencies and out-of-bounds values """ # Init pose data self._translation = numpy.zeros(3) self._rotation = numpy.zeros(3) self._succeded = False - self._validity = 0 - self._unvalid = {} + self._consistent_markers = {} + self._unconsistencies = {} # Don't try to estimate pose if there is no tracked markers if len(tracked_markers) == 0: - return self._translation, self._rotation, self._succeded, self._validity, self._unvalid + return self._translation, self._rotation, self._succeded, self._consistent_markers, self._unconsistencies - # Look for places related to tracked markers - tracked_places = {} + # Look for tracked markers which belong to the scene and store them by name + scene_markers = {} for (marker_id, marker) in tracked_markers.items(): try: name = self.__identifier_cache[marker_id] - tracked_places[name] = marker + scene_markers[name] = marker except KeyError: continue #print('-------------- ArUcoScene pose estimation --------------') - # Pose validity checking is'nt possible when only one place of the scene is tracked - if len(tracked_places.keys()) == 1: + # Pose consistency checking is'nt possible when only one marker is tracked + if len(scene_markers) == 1: - # Get scene pose from to the unique place pose - name, place = tracked_places.popitem() - F, _ = cv.Rodrigues(place.rotation) + # Get scene pose from to the unique marker + name, marker = scene_markers.popitem() + F, _ = cv.Rodrigues(marker.rotation) - self._rotation, self._translation = self.__normalise_place_pose(name, place, F) + self._rotation, self._translation = self.__normalise_marker_pose(name, marker, F) self._succeded = True - self._validity = 1 + self._consistent_markers[name] = marker #print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') #print(f'ArUcoScene rotation vector: {self._rotation[0][0]:3f} {self._rotation[1][0]:3f} {self._rotation[2][0]:3f}') #print(f'ArUcoScene translation vector: {self._translation[0]:3f} {self._translation[1]:3f} {self._translation[2]:3f}') - # Pose validity checking processes places two by two + # Pose consistency checking processes markers two by two else: - valid_places = [] - valid_rvecs = [] - valid_tvecs = [] + consistent_markers = [] + consistent_rvecs = [] + consistent_tvecs = [] - for (A_name, A_place), (B_name, B_place) in itertools.combinations(tracked_places.items(), 2): + for (A_name, A_marker), (B_name, B_marker) in itertools.combinations(scene_markers.items(), 2): #print(f'** {A_name} > {B_name}') - # Get place rotation estimation + # Get marker rotation estimation # Use rotation matrix instead of rotation vector - A, _ = cv.Rodrigues(A_place.rotation) - B, _ = cv.Rodrigues(B_place.rotation) + A, _ = cv.Rodrigues(A_marker.rotation) + B, _ = cv.Rodrigues(B_marker.rotation) - # Rotation matrix from A place to B place + # Rotation matrix from A marker to B marker AB = B.dot(A.T) assert(self.__is_rotation_matrix(AB)) @@ -403,102 +403,102 @@ class ArUcoScene(): angle = numpy.rad2deg(numpy.arccos((numpy.trace(AB) - 1) / 2)) expected_angle = self.__angle_cache[A_name][B_name] - # Calculate distance between A place center and B place center - distance = numpy.linalg.norm(A_place.translation - B_place.translation) + # Calculate distance between A marker center and B marker center + distance = numpy.linalg.norm(A_marker.translation - B_marker.translation) expected_distance = self.__distance_cache[A_name][B_name] - # Check angle and distance according given tolerance then normalise place pose - valid_angle = math.isclose(angle, expected_angle, abs_tol=self.angle_tolerance) - valid_distance = math.isclose(distance, expected_distance, abs_tol=self.distance_tolerance) + # Check angle and distance according given tolerance then normalise marker pose + consistent_angle = math.isclose(angle, expected_angle, abs_tol=self.angle_tolerance) + consistent_distance = math.isclose(distance, expected_distance, abs_tol=self.distance_tolerance) - if valid_angle and valid_distance: + if consistent_angle and consistent_distance: - if A_name not in valid_places: + if A_name not in consistent_markers: - # Remember this place is already validated - valid_places.append(A_name) + # Remember this marker is already validated + consistent_markers.append(A_name) - rvec, tvec = self.__normalise_place_pose(A_name, A_place, A) + rvec, tvec = self.__normalise_marker_pose(A_name, A_marker, A) - # Store normalised place pose - valid_rvecs.append(rvec) - valid_tvecs.append(tvec) + # Store normalised marker pose + consistent_rvecs.append(rvec) + consistent_tvecs.append(tvec) - if B_name not in valid_places: + if B_name not in consistent_markers: - # Remember this place is already validated - valid_places.append(B_name) + # Remember this marker is already validated + consistent_markers.append(B_name) - rvec, tvec = self.__normalise_place_pose(B_name, B_place, B) + rvec, tvec = self.__normalise_marker_pose(B_name, B_marker, B) - # Store normalised place pose - valid_rvecs.append(rvec) - valid_tvecs.append(tvec) + # Store normalised marker pose + consistent_rvecs.append(rvec) + consistent_tvecs.append(tvec) else: - if not valid_angle: - self._unvalid[f'{A_name}/{B_name} angle'] = angle + if not consistent_angle: + self._unconsistencies[f'{A_name}/{B_name} angle'] = angle - if not valid_distance: - self._unvalid[f'{A_name}/{B_name} distance'] = distance + if not consistent_distance: + self._unconsistencies[f'{A_name}/{B_name} distance'] = distance - if len(valid_places) > 1: + if len(consistent_markers) > 1: - # Consider ArUcoScene rotation as the mean of all valid translations + # Consider ArUcoScene rotation as the mean of all consistent translations # !!! WARNING !!! This is a bad hack : processing rotations average is a very complex problem that needs to well define the distance calculation method before. - self._rotation = numpy.mean(numpy.array(valid_rvecs), axis=0) + self._rotation = numpy.mean(numpy.array(consistent_rvecs), axis=0) - # Consider ArUcoScene translation as the mean of all valid translations - self._translation = numpy.mean(numpy.array(valid_tvecs), axis=0) + # Consider ArUcoScene translation as the mean of all consistent translations + self._translation = numpy.mean(numpy.array(consistent_tvecs), axis=0) #print(':::::::::::::::::::::::::::::::::::::::::::::::::::') #print(f'ArUcoScene rotation vector: {self._rotation[0][0]:3f} {self._rotation[1][0]:3f} {self._rotation[2][0]:3f}') #print(f'ArUcoScene translation vector: {self._translation[0]:3f} {self._translation[1]:3f} {self._translation[2]:3f}') self._succeded = True - self._validity = len(valid_places) + self._consistent_markers = consistent_markers else: - unvalid_rvecs = [] - unvalid_tvecs = [] + unconsistent_rvecs = [] + unconsistent_tvecs = [] - # Gather unvalid pose estimations - for name, place in tracked_places.items(): + # Gather unconsistent pose estimations + for name, marker in scene_markers.items(): - if name not in valid_places: + if name not in consistent_markers: - R, _ = cv.Rodrigues(place.rotation) - rvec, tvec = self.__normalise_place_pose(name, place, R) + R, _ = cv.Rodrigues(marker.rotation) + rvec, tvec = self.__normalise_marker_pose(name, marker, R) - unvalid_rvecs = [rvec] - unvalid_tvecs = [tvec] + unconsistent_rvecs = [rvec] + unconsistent_tvecs = [tvec] - # Consider ArUcoScene rotation as the mean of all unvalid translations + # Consider ArUcoScene rotation as the mean of all unconsistent translations # !!! WARNING !!! This is a bad hack : processing rotations average is a very complex problem that needs to well define the distance calculation method before. - self._rotation = numpy.mean(numpy.array(unvalid_rvecs), axis=0) + self._rotation = numpy.mean(numpy.array(unconsistent_rvecs), axis=0) - # Consider ArUcoScene translation as the mean of all unvalid translations - self._translation = numpy.mean(numpy.array(unvalid_tvecs), axis=0) + # Consider ArUcoScene translation as the mean of all unconsistent translations + self._translation = numpy.mean(numpy.array(unconsistent_tvecs), axis=0) #print(':::::::::::::::::::::::::::::::::::::::::::::::::::') #print(f'ArUcoScene rotation vector: {self._rotation[0][0]:3f} {self._rotation[1][0]:3f} {self._rotation[2][0]:3f}') #print(f'ArUcoScene translation vector: {self._translation[0]:3f} {self._translation[1]:3f} {self._translation[2]:3f}') self._succeded = False - self._validity = len(tracked_places) + self._consistent_markers = {} #print('----------------------------------------------------') - return self._translation, self._rotation, self._succeded, self._validity, self._unvalid + return self._translation, self._rotation, self._succeded, self._consistent_markers, self._unconsistencies @property def translation(self) -> numpy.array: """Access to scene translation vector. .. warning:: - Setting scene translation vector implies succeded status to be True and validity score to be 0.""" + Setting scene translation vector implies succeded status to be True and consistency score to be 0.""" return self._translation @@ -507,14 +507,14 @@ class ArUcoScene(): self._translation = tvec self._succeded = True - self._validity = 0 + self._consistent_markers = 0 @property def rotation(self) -> numpy.array: """Access to scene rotation vector. .. warning:: - Setting scene rotation vector implies succeded status to be True and validity score to be 0.""" + Setting scene rotation vector implies succeded status to be True and consistency score to be 0.""" return self._translation @@ -523,7 +523,7 @@ class ArUcoScene(): self._rotation = rvec self._succeded = True - self._validity = 0 + self._consistent_markers = 0 @property def succeded(self) -> bool: @@ -532,10 +532,10 @@ class ArUcoScene(): return self._succeded @property - def validity(self) -> int: - """Access to scene pose estimation validity score.""" + def consistency(self) -> int: + """Access to scene pose estimation consistency score.""" - return self._validity + return len(self._consistent_markers) def draw(self, frame, K, D, draw_places=True): """Draw scene axis and places.""" @@ -543,9 +543,9 @@ class ArUcoScene(): l = self.__marker_size / 2 ll = self.__marker_size - # Select color according validity score - n = 95 * self._validity if self._validity < 2 else 0 - f = 159 * self._validity if self._validity < 2 else 255 + # Select color according consistency score + n = 95 * self.consistency if self.consistency < 2 else 0 + f = 159 * self.consistency if self.consistency < 2 else 255 try: @@ -584,5 +584,5 @@ class ArUcoScene(): print(self._translation) print(self._rotation) print(self._succeded) - print(self._validity) + print(self._consistent_markers) print(axisPoints) diff --git a/src/argaze/__init__.py b/src/argaze/__init__.py index 1e1b5bb..f02a31a 100644 --- a/src/argaze/__init__.py +++ b/src/argaze/__init__.py @@ -2,4 +2,4 @@ .. include:: ../../README.md """ __docformat__ = "restructuredtext" -__all__ = ['utils','ArUcoMarkers','AreaOfInterest','GazeFeatures','DataStructures','GazeAnalysis','ArGazeScene','TobiiGlassesPro2']
\ No newline at end of file +__all__ = ['utils','ArUcoMarkers','AreaOfInterest','GazeFeatures','DataStructures','GazeAnalysis','ArScene','TobiiGlassesPro2']
\ No newline at end of file diff --git a/src/argaze/utils/tobii_segment_argaze_scene_export.py b/src/argaze/utils/tobii_segment_arscene_export.py index a038e34..7bbef59 100644 --- a/src/argaze/utils/tobii_segment_argaze_scene_export.py +++ b/src/argaze/utils/tobii_segment_arscene_export.py @@ -98,13 +98,16 @@ def main(): # Access to video timestamp data buffer tobii_ts_vts = tobii_segment_data['VideoTimeStamp'] + # Access to timestamped gaze position data buffer + tobii_ts_gaze_positions = tobii_segment_data['GazePosition'] + # Prepare video exportation at the same format than segment video output_video = TobiiVideo.TobiiVideoOutput(vs_video_filepath, tobii_segment_video.stream) - # Load argaze project - argaze_scene = ArGazeScene.ArGazeScene.from_json(args.project_path) + # Load ar scene + ar_scene = ArScene.ArScene.from_json(args.project_path) - print(argaze_scene) + print(ar_scene) # Create timestamped buffer to store AOIs and primary time stamp offset ts_offset_aois = DataStructures.TimeStampedBuffer() @@ -132,18 +135,18 @@ def main(): # Get nearest video timestamp _, nearest_vts = tobii_ts_vts.get_last_before(video_ts) - projected_aois['offset'] = nearest_vts + projected_aois['offset'] = nearest_vts.offset # Hide frame left and right borders before tracking to ignore markers outside focus area cv.rectangle(video_frame.matrix, (0, 0), (int(video_frame.width/6), int(video_frame.height)), (0, 0, 0), -1) cv.rectangle(video_frame.matrix, (int(video_frame.width*(1 - 1/6)), 0), (int(video_frame.width), int(video_frame.height)), (0, 0, 0), -1) # Project scene into frame - scene_projection, unvalid = argaze_scene.project(video_frame.matrix, valid_markers=1, visual_hfov=TobiiSpecifications.VISUAL_HFOV) + scene_projection, unconsistencies = ar_scene.project(video_frame.matrix, consistent_markers_number=1, visual_hfov=TobiiSpecifications.VISUAL_HFOV) - # DEBUG: print unvalid distances or angles - for key, value in unvalid.items(): - print(f'{video_ts}: Unvalid {key}: {value}.') + # DEBUG: print unconsistencies distances or angles + for key, value in unconsistencies.items(): + print(f'{video_ts}: Unconsistent {key}: {value}') # Store all projected aoi for aoi_name in scene_projection.keys(): @@ -151,7 +154,7 @@ def main(): projected_aois[aoi_name] = numpy.rint(scene_projection[aoi_name]).astype(int) # Draw tracked markers - argaze_scene.aruco_tracker.draw_tracked_markers(visu_frame.matrix) + ar_scene.aruco_tracker.draw_tracked_markers(visu_frame.matrix) # Draw scene projection scene_projection.draw(visu_frame.matrix, (0, 0), color=(0, 255, 255)) @@ -159,10 +162,10 @@ def main(): # Catch warnings raised by project_scene method except UserWarning as w: - projected_aois['warning'] = w + projected_aois['comment'] = w # Draw tracked markers - argaze_scene.aruco_tracker.draw_tracked_markers(visu_frame.matrix) + ar_scene.aruco_tracker.draw_tracked_markers(visu_frame.matrix) if w == 'Pose estimation fails': @@ -174,7 +177,14 @@ def main(): # Raised when timestamped buffer is empty except KeyError as e: - pass + + e = 'VideoTimeStamp missing' + + projected_aois['offset'] = 0 + projected_aois['comment'] = e + + cv.rectangle(visu_frame.matrix, (0, 50), (550, 100), (127, 127, 127), -1) + cv.putText(visu_frame.matrix, str(e), (20, 80), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 1, cv.LINE_AA) # Store projected AOI ts_offset_aois[video_ts] = projected_aois @@ -218,7 +228,7 @@ def main(): # Print aruco tracking metrics print('\nAruco marker tracking metrics') - try_count, tracked_counts = argaze_scene.aruco_tracker.track_metrics + try_count, tracked_counts = ar_scene.aruco_tracker.track_metrics for marker_id, tracked_count in tracked_counts.items(): print(f'Markers {marker_id} has been detected in {tracked_count} / {try_count} frames ({round(100 * tracked_count / try_count, 2)} %)') |