Setup ArUco markers scene ========================= The OpenCV library provides a module to detect fiducial markers into a picture and estimate its pose (cf [OpenCV ArUco tutorial page](https://docs.opencv.org/4.x/d5/dae/tutorial_aruco_detection.html)). ![OpenCV ArUco markers](https://pyimagesearch.com/wp-content/uploads/2020/12/aruco_generate_tags_header.png) The ArGaze [ArUcoMarkers submodule](../../argaze.md/#argaze.ArUcoMarkers) eases markers creation and description of their expected place for further camera pose estimation. ## Print ArUco markers from a ArUco dictionary ArUco markers always belongs to a set of markers called ArUco markers dictionary. ![ArUco dictionaries](../../img/aruco_dictionaries.png) Many ArUco dictionaries exist with properties concerning the format, the number of markers or the difference between each markers to avoid error in tracking. Here is the documention [about ArUco markers dictionaries](https://docs.opencv.org/3.4/d9/d6a/group__aruco.html#gac84398a9ed9dd01306592dd616c2c975). The creation of [ArUcoMarkers](../../argaze.md/#argaze.ArUcoMarkers.ArUcoMarker) pictures from a dictionary is illustrated in the code below: ``` python from argaze.ArUcoMarkers import ArUcoMarkersDictionary # Create a dictionary of specific April tags aruco_dictionary = ArUcoMarkersDictionary.ArUcoMarkersDictionary('DICT_APRILTAG_16h5') # Export marker n°5 as 3.5 cm picture with 300 dpi resolution aruco_dictionary.create_marker(5, 3.5).save('./markers/', 300) # Export all dictionary markers as 3.5 cm pictures with 300 dpi resolution aruco_dictionary.save('./markers/', 3.5, 300) ``` Let's print some of them before to go further. !!! warning Print markers with a blank zone around them to help in their detection. ## Describe expected ArUco markers place Once [ArUcoMarkers](../../argaze.md/#argaze.ArUcoMarkers.ArUcoMarker) pictures are placed into a scene it is possible to describe their expected 3D place into a file. ![ArUco scene](../../img/aruco_scene.png) Where ever the origin point is, all expected markers places need to be described in a [right-handed 3D axis](https://robotacademy.net.au/lesson/right-handed-3d-coordinate-frame/) where: * +X is pointing to the right, * +Y is pointing to the top, * +Z is pointing to the backward. !!! warning All ArUco markers spatial values must be given in **centimeters**. ### Edit OBJ file description OBJ file format could be exported from most 3D editors. ``` obj o DICT_APRILTAG_16h5#0_Marker v -5.000000 14.960000 0.000000 v 0.000000 14.960000 0.000000 v -5.000000 19.959999 0.000000 v 0.000000 19.959999 0.000000 vn 0.0000 0.0000 1.0000 s off f 1//1 2//1 4//1 3//1 o DICT_APRILTAG_16h5#1_Marker v 25.000000 14.960000 0.000000 v 30.000000 14.960000 0.000000 v 25.000000 19.959999 0.000000 v 30.000000 19.959999 0.000000 vn 0.0000 0.0000 1.0000 s off f 5//2 6//2 8//2 7//2 o DICT_APRILTAG_16h5#2_Marker v -5.000000 -5.000000 0.000000 v 0.000000 -5.000000 0.000000 v -5.000000 0.000000 0.000000 v 0.000000 0.000000 0.000000 vn 0.0000 0.0000 1.0000 s off f 9//3 10//3 12//3 11//3 o DICT_APRILTAG_16h5#3_Marker v 25.000000 -5.000000 0.000000 v 30.000000 -5.000000 0.000000 v 25.000000 0.000000 0.000000 v 30.000000 0.000000 0.000000 vn 0.0000 0.0000 1.0000 s off f 13//4 14//4 16//4 15//4 ``` Here are common OBJ file features needed to describe ArUco markers place: * Object lines (line starting with *o* key) indicate markers dictionary and id by following a format: **DICTIONARY**#**ID**\_Marker. * Vertice lines (lines starting with *v* key) indicate markers corners. The marker size will be automatically deducted from the geometry. * Plane normals (lines starting with *vn* key) need to be exported for further pose estimation. * Face (lines starting with *f* key) link vertices and normals indexes together. !!! warning All markers must have the same size and belong to the same dictionary. ### Edit JSON file description JSON file format allows to describe markers places using translation and euler angle rotation vectors. ``` json { "dictionary": "DICT_APRILTAG_16h5", "marker_size": 5, "places": { "0": { "translation": [-2.5, 17.5, 0], "rotation": [0.0, 0.0, 0.0] }, "1": { "translation": [27.5, 17.5, 0], "rotation": [0.0, 0.0, 0.0] }, "2": { "translation": [-2.5, -2.5, 0], "rotation": [0.0, 0.0, 0.0] }, "3": { "translation": [27.5, -2.5, 0], "rotation": [0.0, 0.0, 0.0] } } } ```