diff options
-rw-r--r-- | src/argaze/GazeAnalysis/TransitionMatrix.py (renamed from src/argaze/GazeAnalysis/TransitionProbabilityMatrix.py) | 6 | ||||
-rw-r--r-- | src/argaze/GazeAnalysis/__init__.py | 2 | ||||
-rw-r--r-- | src/argaze/utils/demo_gaze_features_run.py | 43 |
3 files changed, 31 insertions, 20 deletions
diff --git a/src/argaze/GazeAnalysis/TransitionProbabilityMatrix.py b/src/argaze/GazeAnalysis/TransitionMatrix.py index 62f0500..d85bd0b 100644 --- a/src/argaze/GazeAnalysis/TransitionProbabilityMatrix.py +++ b/src/argaze/GazeAnalysis/TransitionMatrix.py @@ -17,7 +17,7 @@ import pandas @dataclass class AOIScanPathAnalyzer(GazeFeatures.AOIScanPathAnalyzer): - """Implementation of transition probability matrix algorithm as described in ... + """Implementation of transition matrix probabilities and density algorithm as described in ... """ def __post_init__(self): @@ -35,5 +35,7 @@ class AOIScanPathAnalyzer(GazeFeatures.AOIScanPathAnalyzer): sequence.append(aoi_scan_step.aoi) - return pandas.crosstab(pandas.Series(sequence[1:], name='to'), pandas.Series(sequence[:-1], name='from'), normalize=1) + transition_matrix_probabilities = pandas.crosstab(pandas.Series(sequence[1:], name='to'), pandas.Series(sequence[:-1], name='from'), normalize=1) + transition_matrix_density = (transition_matrix_probabilities == 0.).astype(int).sum(axis=1).sum() / transition_matrix_probabilities.size + return transition_matrix_probabilities , transition_matrix_density diff --git a/src/argaze/GazeAnalysis/__init__.py b/src/argaze/GazeAnalysis/__init__.py index faddbce..a980ed3 100644 --- a/src/argaze/GazeAnalysis/__init__.py +++ b/src/argaze/GazeAnalysis/__init__.py @@ -2,4 +2,4 @@ .. include:: README.md """ __docformat__ = "restructuredtext" -__all__ = ['DispersionThresholdIdentification', 'VelocityThresholdIdentification', 'TransitionProbabilityMatrix', 'CoefficientK']
\ No newline at end of file +__all__ = ['DispersionThresholdIdentification', 'VelocityThresholdIdentification', 'TransitionMatrix', 'CoefficientK']
\ No newline at end of file diff --git a/src/argaze/utils/demo_gaze_features_run.py b/src/argaze/utils/demo_gaze_features_run.py index 67c7a52..5ab3ed0 100644 --- a/src/argaze/utils/demo_gaze_features_run.py +++ b/src/argaze/utils/demo_gaze_features_run.py @@ -72,14 +72,20 @@ def main(): 'I-DT': DispersionThresholdIdentification.GazeMovementIdentifier(args.deviation_max_threshold, args.duration_min_threshold), 'I-VT': VelocityThresholdIdentification.GazeMovementIdentifier(args.velocity_max_threshold, args.duration_min_threshold) } + fixation_color = { + 'I-DT': (0, 255, 255), + 'I-VT': (255, 0, 255) + } + current_fixation_color = (255, 255, 0) identification_mode = 'I-DT' raw_scan_path = GazeFeatures.ScanPath() aoi_scan_path = GazeFeatures.AOIScanPath() - tpm = TransitionProbabilityMatrix.AOIScanPathAnalyzer() - tpm_analysis = pandas.DataFrame() - enable_tpm_analysis = False + tm = TransitionMatrix.AOIScanPathAnalyzer() + tm_probabilities = pandas.DataFrame() + tm_density = 0. + enable_tm_analysis = False raw_cK_analyzer = CoefficientK.ScanPathAnalyzer() raw_cK_analysis = 0 @@ -103,7 +109,8 @@ def main(): nonlocal gaze_spread_buffer nonlocal heatmap_matrix nonlocal clear_sum_and_buffer - nonlocal tpm_analysis + nonlocal tm_probabilities + nonlocal tm_density nonlocal raw_cK_analysis nonlocal aoi_cK_analysis @@ -174,9 +181,9 @@ def main(): # Analyse aoi scan path if new_step and len(aoi_scan_path) > 1: - if enable_tpm_analysis: + if enable_tm_analysis: - tpm_analysis = tpm.analyze(aoi_scan_path) + tm_probabilities, tm_density = tm.analyze(aoi_scan_path) if enable_ck_analysis: @@ -225,7 +232,7 @@ def main(): enable_disable = 'disable' if enable_heatmap else 'enable' buffer_on_off = 'on' if enable_heatmap_buffer else 'off' buffer_enable_disable = 'disable' if enable_heatmap_buffer else 'enable' - cv2.putText(aoi_matrix, f'Heatmap: {on_off} (Press \'h\' key to {enable_disable}), Buffer: {buffer_on_off} (Press \'b\' key to {buffer_enable_disable})', (20, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 1, cv2.LINE_AA) + cv2.putText(aoi_matrix, f'Heatmap: {on_off} (Press \'h\' key to {enable_disable}), Buffer: {buffer_on_off} (Press \'b\' key to {buffer_enable_disable})', (20, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255) if enable_heatmap else (255, 255, 255), 1, cv2.LINE_AA) # Draw gaze spread heatmap if enable_heatmap: @@ -235,17 +242,17 @@ def main(): else: # Write identification mode - cv2.putText(aoi_matrix, f'Gaze movement identification mode: {identification_mode} (Press \'m\' key to switch)', (20, 80), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 1, cv2.LINE_AA) + cv2.putText(aoi_matrix, f'Gaze movement identification mode: {identification_mode} (Press \'m\' key to switch)', (20, 80), cv2.FONT_HERSHEY_SIMPLEX, 1, fixation_color[identification_mode], 1, cv2.LINE_AA) # Write TPM help - on_off = 'on' if enable_tpm_analysis else 'off' - display_hide = 'hide' if enable_tpm_analysis else 'display' - cv2.putText(aoi_matrix, f'Transition matrix probability: {on_off} (Press \'t\' key to {display_hide})', (20, 120), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 1, cv2.LINE_AA) + on_off = 'on' if enable_tm_analysis else 'off' + display_hide = 'hide' if enable_tm_analysis else 'display' + cv2.putText(aoi_matrix, f'Transition matrix: {on_off} (Press \'t\' key to {display_hide})', (20, 120), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255) if enable_tm_analysis else (255, 255, 255), 1, cv2.LINE_AA) # Write cK help on_off = 'on' if enable_ck_analysis else 'off' display_hide = 'hide' if enable_ck_analysis else 'display' - cv2.putText(aoi_matrix, f'coefficient K: {on_off} (Press \'k\' key to {display_hide})', (20, 160), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 1, cv2.LINE_AA) + cv2.putText(aoi_matrix, f'coefficient K: {on_off} (Press \'k\' key to {display_hide})', (20, 160), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255) if enable_ck_analysis else (255, 255, 255), 1, cv2.LINE_AA) # Check fixation identification if gaze_movement_identifier[identification_mode].current_fixation != None: @@ -256,7 +263,7 @@ def main(): aoi_scene_projection.draw_circlecast(aoi_matrix, current_fixation.focus, current_fixation.deviation_max, base_color=(0, 0, 0), matching_color=(255, 255, 255)) # Draw current fixation - current_fixation.draw(aoi_matrix, color=(255, 255, 0)) + current_fixation.draw(aoi_matrix, color=current_fixation_color) # Draw current fixation gaze positions current_fixation.draw_positions(aoi_matrix) @@ -278,7 +285,7 @@ def main(): current_saccade.draw_positions(aoi_matrix) # Draw last 10 steps of raw scan path - raw_scan_path.draw(aoi_matrix, fixation_color=(255, 0, 255), deepness=10) + raw_scan_path.draw(aoi_matrix, fixation_color=fixation_color[identification_mode], deepness=10) # Write last 5 steps of aoi scan path path = '' @@ -291,9 +298,11 @@ def main(): cv2.putText(aoi_matrix, path, (20, window_size[1]-40), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 1, cv2.LINE_AA) # Draw transition probability matrix - if enable_tpm_analysis: + if enable_tm_analysis: - for from_aoi, column in tpm_analysis.items(): + cv2.putText(aoi_matrix, f'Transition matrix density: {tm_density:.2f}', (20, window_size[1]-160), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 1, cv2.LINE_AA) + + for from_aoi, column in tm_probabilities.items(): for to_aoi, probability in column.items(): @@ -367,7 +376,7 @@ def main(): # Enable TPM analysis with 't' key if key_pressed == 116: - enable_tpm_analysis = not enable_tpm_analysis + enable_tm_analysis = not enable_tm_analysis # Stop calibration by pressing 'Esc' key if cv2.waitKey(10) == 27: |