aboutsummaryrefslogtreecommitdiff
path: root/docs/user_guide/aruco_markers_pipeline/aruco_camera_configuration_and_execution.md
blob: a0ec2bf9d19aebf9d8477f6ec5786d07d79cfb5a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
Configure and execute ArUcoCamera
=================================

Once [ArUco markers are placed into a scene](aruco_scene_creation.md) and [the camera optic have been calibrated](optic_parameters_calibration.md), everything is ready to setup an ArUco marker pipeline thanks to [ArUcoCamera](../../argaze.md/#argaze.ArUcoMarkers.ArUcoCamera) class.

As it inherits from [ArFrame](../../argaze.md/#argaze.ArFeatures.ArFrame), the [ArUcoCamera](../../argaze.md/#argaze.ArUcoMarkers.ArUcoCamera) class benefits from all the services of a [gaze analysis pipeline](./user_guide/gaze_analysis_pipeline/introduction.md). 

Besides, the [ArUcoCamera](../../argaze.md/#argaze.ArUcoMarkers.ArUcoCamera) class projects [ArUcoScenes](../../argaze.md/#argaze.ArUcoMarkers.ArUcoScene)'s layers into its own layers thanks to ArUco markers pose estimations made by its [ArUcoDetector](../../argaze.md/#argaze.ArUcoMarkers.ArUcoDetector).

![ArUco camera frame](../../img/aruco_camera_frame.png)

## Load JSON configuration file

The [ArUcoCamera](../../argaze.md/#argaze.ArUcoMarkers.ArUcoCamera) internal pipeline loads from a JSON configuration file thanks to [ArUcoCamera.from_json](../../argaze.md/#argaze.ArUcoMarkers.ArUcoCamera.from_json) class method. 

Here is a simple JSON ArUcoCamera configuration file example:

```json
{
	"name": "My FullHD camera",
	"size": [1920, 1080],
	"aruco_detector": {
        "dictionary": {
            "name": "DICT_APRILTAG_16h5"
        },
        "marker_size": 5,
        "optic_parameters": "optic_parameters.json",
        "parameters": {
            "cornerRefinementMethod": 1,
            "aprilTagQuadSigma": 2,
            "aprilTagDeglitch": 1
        }
    },
    "scenes": {

    },
    "layers": {
        "main_layer": {}
    },
}
```

Then, here is how to load the JSON file:

```python
from argaze.ArUcoMarkers import ArUcoCamera

# Load ArUcoCamera
aruco_camera = ArUcoCamera.ArUcoCamera.from_json('./configuration.json')
```

Now, let's understand the meaning of each JSON entry.

### Name

The name of the [ArUcoCamera](../../argaze.md/#argaze.ArUcoMarkers.ArUcoCamera). Basically useful for visualisation purpose.

### Size

The size of the [ArUcoCamera](../../argaze.md/#argaze.ArUcoMarkers.ArUcoCamera) defines the dimension of the rectangular area where gaze positions are projected. Be aware that gaze positions have to be in the same range of value.

!!! warning
	**ArGaze doesn't impose any spatial unit.** Gaze positions can either be integer or float, pixels, millimeters or what ever you need. The only concern is that all spatial values used in further configurations have to be all the same unit.

### ArUco detector

The first [ArFrame](../../argaze.md/#argaze.ArFeatures.ArFrame) pipeline step is to identify fixations or saccades from consecutive timestamped gaze positions.

![Gaze Movement Identifier](../../img/ar_frame_gaze_movement_identifier.png)

The identification algorithm can be selected by instantiating a particular [GazeMovementIdentifier](../../argaze.md/#argaze.GazeFeatures.GazeMovementIdentifier) from the [argaze.GazeAnalysis](../../argaze.md/#argaze.GazeAnalysis) submodule or [from another python package](advanced_topics/module_loading.md).

In the example file, the choosen identification algorithm is the [Dispersion Threshold Identification (I-DT)](../../argaze.md/#argaze.GazeAnalysis.DispersionThresholdIdentification) which has two specific *deviation_max_threshold* and *duration_min_threshold* attributes.

!!! note
	In ArGaze, [Fixation](../../argaze.md/#argaze.GazeFeatures.Fixation) and [Saccade](../../argaze.md/#argaze.GazeFeatures.Saccade) are considered as particular [GazeMovements](../../argaze.md/#argaze.GazeFeatures.GazeMovement).

!!! warning
	JSON *gaze_movement_identifier* entry is mandatory. Otherwise, the ScanPath and ScanPathAnalyzers steps are disabled.

### Scan Path

The second [ArFrame](../../argaze.md/#argaze.ArFeatures.ArFrame) pipeline step aims to build a [ScanPath](../../argaze.md/#argaze.GazeFeatures.ScanPath) defined as a list of [ScanSteps](../../argaze.md/#argaze.GazeFeatures.ScanStep) made by a fixation and a consecutive saccade.

![Scan Path](../../img/ar_frame_scan_path.png)

Once fixations and saccades are identified, they are automatically appended to the ScanPath if required.

The [ScanPath.duration_max](../../argaze.md/#argaze.GazeFeatures.ScanPath.duration_max) attribute is the duration from which older scan steps are removed each time new scan steps are added.

!!! note
	JSON *scan_path* entry is not mandatory. If scan_path_analyzers entry is not empty, the ScanPath step is automatically enabled.

### Scan Path Analyzers

Finally, the last [ArFrame](../../argaze.md/#argaze.ArFeatures.ArFrame) pipeline step consists in passing the previously built [ScanPath](../../argaze.md/#argaze.GazeFeatures.ScanPath) to each loaded [ScanPathAnalyzer](../../argaze.md/#argaze.GazeFeatures.ScanPathAnalyzer).

Each analysis algorithm can be selected by instantiating a particular [ScanPathAnalyzer](../../argaze.md/#argaze.GazeFeatures.ScanPathAnalyzer) from the [argaze.GazeAnalysis](../../argaze.md/#argaze.GazeAnalysis) submodule or [from another python package](advanced_topics/module_loading.md).

## Pipeline execution

Timestamped gaze positions have to be passed one by one to [ArFrame.look](../../argaze.md/#argaze.ArFeatures.ArFrame.look) method to execute the whole intanciated pipeline.

```python
# Assuming that timestamped gaze positions are available
...

    # Look ArFrame at a timestamped gaze position
    ar_frame.look(timestamp, gaze_position)
```