diff options
Diffstat (limited to 'docs/user_guide/gaze_analysis_pipeline')
3 files changed, 157 insertions, 6 deletions
diff --git a/docs/user_guide/gaze_analysis_pipeline/ar_frame_configuration_and_execution.md b/docs/user_guide/gaze_analysis_pipeline/ar_frame_configuration_and_execution.md index 00300a8..f1264c7 100644 --- a/docs/user_guide/gaze_analysis_pipeline/ar_frame_configuration_and_execution.md +++ b/docs/user_guide/gaze_analysis_pipeline/ar_frame_configuration_and_execution.md @@ -3,7 +3,7 @@ Configure and execute ArFrame The [ArFrame](../../../argaze/#argaze.ArFeatures.ArFrame) class defines a rectangular area where timestamped gaze positions are projected in and inside which they need to be analyzed. -![Timestamped Gaze Positions](../../img/ar_frame.png) +![Empty frame area](../../img/ar_frame_empty.png) ## Load JSON configuration file @@ -22,7 +22,7 @@ Here is a simple JSON ArFrame configuration file example: } }, "scan_path": { - "duration_max": 30000, + "duration_max": 30000 }, "scan_path_analyzers": { "Basic": {}, @@ -60,7 +60,7 @@ print("heatmap:", ar_frame.heatmap) Finally, here is what the program writes in console: -``` +```txt name: My FullHD screen size: [1920, 1080] gaze movement identifier type: <class 'argaze.GazeAnalysis.DispersionThresholdIdentification.GazeMovementIdentifier'> @@ -88,7 +88,7 @@ The first [ArFrame](../../../argaze/#argaze.ArFeatures.ArFrame) pipeline step is The identification method can be selected by instantiating a particular [GazeMovementIdentifier](../../../argaze/#argaze.GazeFeatures.GazeMovementIdentifier) from the [argaze.GazeAnalysis](../../../argaze/#argaze.GazeAnalysis) submodule or [another python package](../advanced_topics/plugin_loading). -In the example file, the choosen identification method is the [Dispersion Threshold Identification (I-DT)](../../../argaze/#argaze.GazeAnalysis.DispersionThresholdIdentification) which has two specific deviation_max_threshold and duration_min_threshold attributes. +In the example file, the choosen identification method is the [Dispersion Threshold Identification (I-DT)](../../../argaze/#argaze.GazeAnalysis.DispersionThresholdIdentification) which has two specific *deviation_max_threshold* and *duration_min_threshold* attributes. !!! note In ArGaze, [Fixation](../../../argaze/#argaze.GazeFeatures.Fixation) and [Saccade](../../../argaze/#argaze.GazeFeatures.Saccade) are considered as particular [GazeMovements](../../../argaze/#argaze.GazeFeatures.GazeMovement). @@ -128,7 +128,7 @@ The Heatmap object have tree attributes to set its size, the sigma point spreadi Timestamped gaze positions have to be passed one by one to [ArFrame.look](../../../argaze/#argaze.ArFeatures.ArFrame.look) method to execute the whole intanciated pipeline. ```python -# Assuming that timestamp gaze positions are available +# Assuming that timestamped gaze positions are available ... # Look ArFrame at a timestamped gaze position diff --git a/docs/user_guide/gaze_analysis_pipeline/ar_layer_configuration_and_execution.md b/docs/user_guide/gaze_analysis_pipeline/ar_layer_configuration_and_execution.md new file mode 100644 index 0000000..c9ca097 --- /dev/null +++ b/docs/user_guide/gaze_analysis_pipeline/ar_layer_configuration_and_execution.md @@ -0,0 +1,151 @@ +Add and execute ArLayer +============================= + +The [ArLayer](../../../argaze/#argaze.ArFeatures.ArLayer) class defines a space where to make matching of gaze movements and AOIs and inside which those matchings need to be analyzed. + +![Empty layer area](../../img/ar_layer_empty.png) + +## Add ArLayer to ArFrame JSON configuration file + +An [ArFrame](../../../argaze/#argaze.ArFeatures.ArFrame) instance can contains multiples [ArLayers](../../../argaze/#argaze.ArFeatures.ArLayer). + +Here is the JSON ArFrame configuration file example where one layer is added: + +```json +{ + "name": "My FullHD screen", + "size": [1920, 1080], + ... + "layers": { + "MyLayer": { + "aoi_scene" : { + "upper_left_corner": [[0, 0], [960, 0], [960, 540], [0, 540]], + "upper_right_corner": [[960, 0], [1920, 0], [1920, 540], [960, 540]], + "lower_left_corner": [[0, 540], [960, 540], [960, 1080], [0, 1080]], + "lower_right_corner": [[960, 540], [1920, 540], [1920, 1080], [960, 1080]] + }, + "aoi_matcher": { + "DeviationCircleCoverage": { + "coverage_threshold": 0.5 + } + }, + "aoi_scan_path": { + "duration_max": 30000 + }, + "aoi_scan_path_analyzers": { + "Basic": {}, + "TransitionMatrix": {}, + "NGram": { + "n_min": 3, + "n_max": 5 + } + } + } + } +} +``` + +Then, after the JSON file being loaded: + +```python +from argaze import ArFeatures + +# Assuming the ArFrame is loaded +... + +# Print ArLayer attributes +for name, ar_layer in ar_frame.layers.items(): + + print("name:", ar_layer.name) + print("AOI scene:", ar_layer.aoi_scene) + print("AOI scan path:", ar_layer.aoi_scan_path) + + for module, analyzer in ar_layer.aoi_scan_path_analyzers.items(): + print('AOI scan path analyzer module:', module) +``` + +Finally, here is what the program writes in console: + +```txt +... + +name: MyLayer +AOI scene: + upper_left_corner: +[[0, 0], [960, 0], [960, 540], [0, 540]] + upper_right_corner: +[[960, 0], [1920, 0], [1920, 540], [960, 540]] + lower_left_corner: +[[0, 540], [960, 540], [960, 1080], [0, 1080]] + lower_right_corner: +[[960, 540], [1920, 540], [1920, 1080], [960, 1080]] +AOI scan path: [] +AOI scan path analyzer module: argaze.GazeAnalysis.Basic +AOI scan path analyzer module: argaze.GazeAnalysis.TransitionMatrix +AOI scan path analyzer module: argaze.GazeAnalysis.NGram +``` + +Now, let's understand the meaning of each JSON entry. + +### Name + +The name of the [ArLayer](../../../argaze/#argaze.ArFeatures.ArLayer). Basically useful for visualisation purpose. + +### AOI Scene + +The [AOIScene](../../../argaze/#argaze.AreaOfInterest.AOIFeatures.AOIScene) defines a set of 2D [AreaOfInterest](../../../argaze/#argaze.AreaOfInterest.AOIFeatures.AreaOfInterest) registered by name. + +![AOI Scene](../../img/ar_layer_aoi_scene.png) + +### AOI Matcher + +The first [ArLayer](../../../argaze/#argaze.ArFeatures.ArLayer) pipeline step aims to make match identified gaze movement with an AOI of the scene. + +![AOI Matcher](../../img/ar_layer_aoi_matcher.png) + +The matching method can be selected by instantiating a particular [AOIMatcher](../../../argaze/#argaze.GazeFeatures.AOIMatcher) from the [argaze.GazeAnalysis](../../../argaze/#argaze.GazeAnalysis) submodule or [another python package](../advanced_topics/plugin_loading). + +In the example file, the choosen matching method is the [Deviation Circle Coverage](../../../argaze/#argaze.GazeAnalysis.DeviationCircleCoverage) which has one specific *coverage_threshold* attribute. + +!!! warning + JSON *aoi_matcher* entry is mandatory. Otherwise, the AOIScanPath and AOIScanPathAnalyzers steps are disabled. + +### AOI Scan Path + +The second [ArLayer](../../../argaze/#argaze.ArFeatures.ArLayer) pipeline step aims to build a [AOIScanPath](../../../argaze/#argaze.GazeFeatures.AOIScanPath) defined as a list of [AOIScanSteps](../../../argaze/#argaze.GazeFeatures.AOIScanStep) made by a set of successive fixations/saccades onto a same AOI. + +![AOI Scan Path](../../img/ar_layer_aoi_scan_path.png) + +Once fixations and saccades are identified and fixations are matched to AOI, they are automatically appended to the AOIScanPath if required. + +The [AOIScanPath.duration_max](../../../argaze/#argaze.GazeFeatures.AOIScanPath.duration_max) attribute is the duration from which older AOI scan steps are removed each time new AOI scan steps are added. + +### AOI Scan Path Analyzers + +Finally, the last [ArLayer](../../../argaze/#argaze.ArFeatures.ArLayer) pipeline step consists in passing the previously built [AOIScanPath](../../../argaze/#argaze.GazeFeatures.AOIScanPath) to each loaded [AOIScanPathAnalyzer](../../../argaze/#argaze.GazeFeatures.AOIScanPathAnalyzer). + +Each analysis algorithm can be selected by instantiating a particular [AOIScanPathAnalyzer](../../../argaze/#argaze.GazeFeatures.AOIScanPathAnalyzer) from the [argaze.GazeAnalysis](../../../argaze/#argaze.GazeAnalysis) submodule or [another python package](../advanced_topics/plugin_loading). + +!!! note + JSON *aoi_scan_path* entry is not mandatory. If aoi_scan_path_analyzers entry is not empty, the AOIScanPath step is automatically enabled. + +## Pipeline execution + +Timestamped gaze movements identified by parent ArFrame are passed one by one to each [ArLayer.look](../../../argaze/#argaze.ArFeatures.ArLayer.look) method to execute each layer intanciated pipeline. + +```python +# Assuming that timestamped gaze positions are available +... + + # Look ArFrame at a timestamped gaze position + movement, _, layers_analysis, _, _ = ar_frame.look(timestamp, gaze_position) + + # Check if a movement has been identified + if movement.valid and movement.finished: + + # Do something with each layer AOI scan path analysis + for layer_name, layer_aoi_scan_path_analysis in layers_analysis.items(): + for module, analysis in layer_aoi_scan_path_analysis.items(): + for data, value in analysis.items(): + ... +``` diff --git a/docs/user_guide/gaze_analysis_pipeline/introduction.md b/docs/user_guide/gaze_analysis_pipeline/introduction.md index 568cba2..ee67c9d 100644 --- a/docs/user_guide/gaze_analysis_pipeline/introduction.md +++ b/docs/user_guide/gaze_analysis_pipeline/introduction.md @@ -11,7 +11,7 @@ To build your own gaze analysis pipeline, you need to know: * [How to edit timestamped gaze positions](../timestamped_gaze_positions_edition), * [How to deal with an ArFrame instance](../ar_frame_configuration_and_execution), -* [How to setup Areas Of Interest](../ar_frame_aoi_configuration), +* [How to deal with an ArLayer instance](../ar_layer_configuration_and_execution), * [How to log resulted gaze analysis](../analysis). More advanced features are also explained like: |