aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/argaze/ArUcoMarkers/ArUcoMarker.py21
-rw-r--r--src/argaze/ArUcoMarkers/ArUcoMarkersDictionary.py40
-rw-r--r--src/argaze/ArUcoMarkers/README.md2
-rw-r--r--src/argaze/utils/README.md4
-rw-r--r--src/argaze/utils/aruco_markers_export.py5
5 files changed, 43 insertions, 29 deletions
diff --git a/src/argaze/ArUcoMarkers/ArUcoMarker.py b/src/argaze/ArUcoMarkers/ArUcoMarker.py
index ef03ffd..5879a7b 100644
--- a/src/argaze/ArUcoMarkers/ArUcoMarker.py
+++ b/src/argaze/ArUcoMarkers/ArUcoMarker.py
@@ -39,6 +39,16 @@ class ArUcoMarker():
return self.corners[0].mean(axis=0)
+ def image(self, dpi) -> numpy.array:
+ """Create marker matrix image at a given resolution."""
+
+ dimension = round(dpi * self.size / 2.54)
+ matrix = numpy.zeros((dimension, dimension, 1), dtype="uint8")
+
+ aruco.drawMarker(self.dictionary.markers, self.identifier, dimension, matrix, 1)
+
+ return numpy.repeat(matrix, 3).reshape(dimension, dimension, 3)
+
def draw(self, frame, K, D):
"""Draw marker in frame."""
@@ -47,4 +57,13 @@ class ArUcoMarker():
cv.drawFrameAxes(frame, K, D, self.rotation, self.translation, self.size)
- aruco.drawDetectedMarkers(frame, [self.corners], numpy.array([self.identifier])) \ No newline at end of file
+ aruco.drawDetectedMarkers(frame, [self.corners], numpy.array([self.identifier]))
+
+ def save(self, destination_folder, dpi):
+ """Save marker image as .png file."""
+
+ filename = f'{self.dictionary.name}_{self.dictionary.format}_{self.identifier}.png'
+ filepath = f'{destination_folder}/{filename}'
+
+ cv.imwrite(filepath, self.image(dpi))
+
diff --git a/src/argaze/ArUcoMarkers/ArUcoMarkersDictionary.py b/src/argaze/ArUcoMarkers/ArUcoMarkersDictionary.py
index 016c0b5..4f87881 100644
--- a/src/argaze/ArUcoMarkers/ArUcoMarkersDictionary.py
+++ b/src/argaze/ArUcoMarkers/ArUcoMarkersDictionary.py
@@ -1,5 +1,7 @@
#!/usr/bin/env python
+from typing import TypeVar
+
import cv2 as cv
import cv2.aruco as aruco
import numpy
@@ -29,6 +31,9 @@ all_aruco_markers_dictionaries = {
}
"""Dictionnary to list all built-in ArUco markers dictionaries from OpenCV ArUco package."""
+ArUcoMarkerType = TypeVar('ArUcoMarker', bound="ArUcoMarker")
+# Type definition for type annotation convenience
+
class ArUcoMarkersDictionary():
"""Handle an ArUco markers dictionary."""
@@ -49,7 +54,7 @@ class ArUcoMarkersDictionary():
self.__format = '5X5'
self.__number = 1024
- # DICT_APRILTAG_ case
+ # DICT_APRILTAG case
elif self.__format == 'APRILTAG':
april_tag_format = dict_name_split[2]
@@ -80,7 +85,7 @@ class ArUcoMarkersDictionary():
self.__number = int(dict_name_split[2])
self.__aruco_dict = aruco.Dictionary_get(all_aruco_markers_dictionaries[self.__name])
-
+
@property
def name(self)-> str:
"""Get dictionary name."""
@@ -88,7 +93,7 @@ class ArUcoMarkersDictionary():
return self.__name
@property
- def markers(self)-> aruco.Dictionary:
+ def markers(self) -> aruco.Dictionary:
"""Get all markers from dictionary."""
return self.__aruco_dict
@@ -100,38 +105,27 @@ class ArUcoMarkersDictionary():
return self.__format
@property
- def size(self) -> int:
+ def number(self) -> int:
"""Get number of markers inside dictionary."""
return self.__number
- def create_marker(self, i, dpi=300) -> numpy.array:
- """Create a marker image."""
-
- marker = numpy.zeros((dpi, dpi, 1), dtype="uint8")
- aruco.drawMarker(self.__aruco_dict, i, dpi, marker, 1)
-
- return numpy.repeat(marker, 3).reshape(dpi, dpi, 3)
-
- def export_as_png(self, destination_folder, dpi, i):
- """Save one marker into a .png file."""
+ def create_marker(self, i, size) -> ArUcoMarkerType:
+ """Create a marker."""
if i >= 0 and i < self.__number:
- output_filename = f'marker_{self.__format}_{i}.png'
+ from argaze.ArUcoMarkers import ArUcoMarker
- # create marker
- marker = self.create_marker(i, dpi)
-
- # save marker into destination folder
- cv.imwrite(f'{destination_folder}/{output_filename}', marker)
+ return ArUcoMarker.ArUcoMarker(self, i, size)
else:
- raise ValueError(f'Bad ArUco index: {i}')
- def export_all(self, destination_folder, dpi):
+ raise ValueError(f'Bad index: {i}')
+
+ def save(self, destination_folder, size, dpi):
"""Save all markers dictionary into separated .png files."""
for i in range(self.__number):
- self.export_as_png(destination_folder, dpi, i)
+ self.create_marker(i, size).save(destination_folder, dpi)
diff --git a/src/argaze/ArUcoMarkers/README.md b/src/argaze/ArUcoMarkers/README.md
index 011305f..821a582 100644
--- a/src/argaze/ArUcoMarkers/README.md
+++ b/src/argaze/ArUcoMarkers/README.md
@@ -2,7 +2,7 @@ Class interface to work with [OpenCV ArUco markers](https://docs.opencv.org/4.x/
## ArUco markers dictionary
-To work with ArUco markers, you need to choose a marker dictionary which have differents property concerning the difference between each markers to avoid error in tracking.
+To work with ArUco markers, you need to choose a marker dictionary which have specific the format, the numbers of markers or the difference between each markers to avoid error in tracking.
Here is more [about ArUco markers dictionaries](https://docs.opencv.org/3.4/d9/d6a/group__aruco.html#gac84398a9ed9dd01306592dd616c2c975)
## Utils
diff --git a/src/argaze/utils/README.md b/src/argaze/utils/README.md
index fd1c332..2fc3bab 100644
--- a/src/argaze/utils/README.md
+++ b/src/argaze/utils/README.md
@@ -10,10 +10,10 @@ Collection of command-line high level features based on ArGaze toolkit.
### ArUco factory
-- Export all markers from DICT_APRILTAG_16h5 dictionary at 300 dpi into an export/markers folder:
+- Export all markers from DICT_APRILTAG_16h5 dictionary as 5 cm pictures with 300 dpi resolution into an export/markers folder:
```
-python ./src/argaze/utils/aruco_markers_export.py -o export/markers -d DICT_APRILTAG_16h5
+python ./src/argaze/utils/aruco_markers_export.py -o export/markers -d DICT_APRILTAG_16h5 -s 5 -r 300
```
- Export a 7 columns and 5 rows calibration board made of 5cm squares with 3cm markers from DICT_APRILTAG_16h5 dictionary at 50 dpi into an export folder:
diff --git a/src/argaze/utils/aruco_markers_export.py b/src/argaze/utils/aruco_markers_export.py
index ce68761..40d3e20 100644
--- a/src/argaze/utils/aruco_markers_export.py
+++ b/src/argaze/utils/aruco_markers_export.py
@@ -12,7 +12,8 @@ def main():
parser = argparse.ArgumentParser(description=main.__doc__)
parser.add_argument('-o', '--output', metavar='OUT', type=str, default='.', help='destination path')
parser.add_argument('-d', '--dictionary', metavar='DICT', type=ArUcoMarkersDictionary.ArUcoMarkersDictionary, default='DICT_ARUCO_ORIGINAL', help='aruco marker dictionnary (DICT_4X4_50, DICT_4X4_100, DICT_4X4_250, DICT_4X4_1000, DICT_5X5_50, DICT_5X5_100, DICT_5X5_250, DICT_5X5_1000, DICT_6X6_50, DICT_6X6_100, DICT_6X6_250, DICT_6X6_1000, DICT_7X7_50, DICT_7X7_100, DICT_7X7_250, DICT_7X7_1000, DICT_ARUCO_ORIGINAL, DICT_APRILTAG_16h5, DICT_APRILTAG_25h9, DICT_APRILTAG_36h10, DICT_APRILTAG_36h11)')
- parser.add_argument('-r', '--resolution', metavar='RES', type=int, default=300, help='picture resolution in dpi')
+ parser.add_argument('-s', '--size', metavar='SIZE', type=float, default=3., help='marker size in cm')
+ parser.add_argument('-r', '--resolution', metavar='RES', type=int, default=50, help='picture resolution in dpi')
args = parser.parse_args()
# manage destination folder
@@ -21,7 +22,7 @@ def main():
print(f'{args.output} folder created')
# export markers
- args.dictionary.export_all(args.output, args.resolution)
+ args.dictionary.export_all(args.output, args.size, args.resolution)
if __name__ == '__main__':