From 147f3e473bbd0e35cbe754baea329c6b5cb7c2d2 Mon Sep 17 00:00:00 2001 From: Théo de la Hogue Date: Wed, 29 Mar 2023 10:03:39 +0200 Subject: Making ArUcoBoard as dataclass. --- src/argaze.test/ArUcoMarkers/ArUcoBoard.py | 31 ++++------------- src/argaze/ArUcoMarkers/ArUcoBoard.py | 55 ++++++++++++------------------ 2 files changed, 28 insertions(+), 58 deletions(-) (limited to 'src') diff --git a/src/argaze.test/ArUcoMarkers/ArUcoBoard.py b/src/argaze.test/ArUcoMarkers/ArUcoBoard.py index 2c0e3da..65562ad 100644 --- a/src/argaze.test/ArUcoMarkers/ArUcoBoard.py +++ b/src/argaze.test/ArUcoMarkers/ArUcoBoard.py @@ -10,41 +10,24 @@ import numpy class TestArUcoBoardClass(unittest.TestCase): """Test ArUcoBoard class.""" - def test_new_from_dictionary_string(self): - """Test ArUcoBoard creation using a dictionary string.""" + def test_new(self): + """Test ArUcoBoard creation using a dictionary instance.""" - # Check ArUco board creation columns = 4 rows = 3 square_size = 2 marker_size = 1 - aruco_board = ArUcoBoard.ArUcoBoard(columns, rows, square_size, marker_size, 'DICT_ARUCO_ORIGINAL') - - # Check ArUco board - self.assertIsNone(numpy.testing.assert_array_equal(aruco_board.identifiers, [i for i in range(int((columns*rows)/2))])) - self.assertIsNone(numpy.testing.assert_array_equal(aruco_board.size, [columns, rows])) - self.assertEqual(aruco_board.markers_number, int((columns*rows)/2)) - self.assertEqual(aruco_board.corners_number, (columns-1)*(rows-1)) - - def test_new_from_dictionary_instance(self): - """Test ArUcoBoard creation using a dictionary instance.""" - # Check ArUco board creation aruco_dictionary = ArUcoMarkersDictionary.ArUcoMarkersDictionary('DICT_APRILTAG_16h5') - aruco_board = ArUcoBoard.ArUcoBoard(4, 3, 2, 1, aruco_dictionary) + aruco_board = ArUcoBoard.ArUcoBoard(columns, rows, square_size, marker_size, aruco_dictionary) # Check ArUco board dictionary name self.assertEqual(aruco_board.dictionary.name, 'DICT_APRILTAG_16h5') - - def test_new_with_no_dictionary(self): - """Test ArUcoBoard creation using a dictionary instance.""" - - # Check ArUco board creation - aruco_board = ArUcoBoard.ArUcoBoard(4, 3, 2, 1) - - # Check ArUco board dictionary name - self.assertEqual(aruco_board.dictionary.name, 'DICT_ARUCO_ORIGINAL') + self.assertIsNone(numpy.testing.assert_array_equal(aruco_board.identifiers, [i for i in range(int((columns*rows)/2))])) + self.assertIsNone(numpy.testing.assert_array_equal(aruco_board.size, [columns, rows])) + self.assertEqual(aruco_board.markers_number, int((columns*rows)/2)) + self.assertEqual(aruco_board.corners_number, (columns-1)*(rows-1)) if __name__ == '__main__': diff --git a/src/argaze/ArUcoMarkers/ArUcoBoard.py b/src/argaze/ArUcoMarkers/ArUcoBoard.py index 5d2a39d..6c91fc6 100644 --- a/src/argaze/ArUcoMarkers/ArUcoBoard.py +++ b/src/argaze/ArUcoMarkers/ArUcoBoard.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +from dataclasses import dataclass, field from argaze.ArUcoMarkers import ArUcoMarkersDictionary @@ -6,74 +7,60 @@ import numpy import cv2 as cv import cv2.aruco as aruco +@dataclass class ArUcoBoard(): """Calibration chess board with ArUco markers inside.""" - def __init__(self, columns: int, rows: int, square_size: float, marker_size: float, dictionary: ArUcoMarkersDictionary.ArUcoMarkersDictionary | str = None): - """Create columns x rows chess board with ArUco markers at given size in centimeters.""" + columns: int = field(default=0) + """Number of columns.""" - # Store properties - self.__columns = columns - self.__rows = rows - self.__square_size = square_size # in cm - self.__marker_size = marker_size # in cm + rows: int = field(default=0) + """Number of rows.""" - # Handle dictionary str or instance - if dictionary != None: + square_size: float = field(default=0.) + """Size of board square in centimeter.""" - if type(dictionary) == str: - self.dictionary = ArUcoMarkersDictionary.ArUcoMarkersDictionary(dictionary) - elif isinstance(dictionary, ArUcoMarkersDictionary.ArUcoMarkersDictionary): - self.dictionary = dictionary - else: - raise ValueError(f'dictionary: {dictionary}') + marker_size: float = field(default=0.) + """Size of ArUco markers inside board squares in centimeter.""" - else: + dictionary: ArUcoMarkersDictionary.ArUcoMarkersDictionary = field(default_factory=ArUcoMarkersDictionary.ArUcoMarkersDictionary) + """ArUco markers dictionary.""" - self.dictionary = ArUcoMarkersDictionary.ArUcoMarkersDictionary() + def __post_init__(self): # Create board model - self.__board = aruco.CharucoBoard((self.__columns, self.__rows), self.__square_size/100., self.__marker_size/100., self.dictionary.markers) - - def __del__(self): - pass - - @property - def model(self) -> aruco.CharucoBoard: - """Get the board model.""" - - return self.__board + self.model = aruco.CharucoBoard((self.columns, self.rows), self.square_size/100., self.marker_size/100., self.dictionary.markers) @property def identifiers(self) -> list[int]: """Get board markers identifiers.""" - return self.__board.getIds() + return self.model.getIds() @property def size(self)-> int: """Get numbers of columns and rows.""" - return self.__board.getChessboardSize() + return self.model.getChessboardSize() @property def markers_number(self) -> int: """Get number of markers.""" - return len(self.__board.getIds()) + return len(self.model.getIds()) @property def corners_number(self) -> int: """Get number of corners.""" - return (self.__board.getChessboardSize()[0] - 1 ) * (self.__board.getChessboardSize()[1] - 1) + return (self.model.getChessboardSize()[0] - 1 ) * (self.model.getChessboardSize()[1] - 1) def save(self, destination_folder: str, dpi: int): """Save a picture of the calibration board into a destination folder.""" - output_filename = f'{self.__dictionary.name}_{self.__marker_size}cm_{self.__columns*self.__square_size}cmx{self.__rows*self.__square_size}cm.png' + output_filename = f'{self.dictionary.name}_{self.marker_size}cm_{self.columns*self.square_size}cmx{self.rows*self.square_size}cm.png' - dimension = [round(d * self.__board.getSquareLength() * 100 * dpi / 2.54) for d in self.__board.getChessboardSize()] # 1 cm = 2.54 inches + dimension = [round(d * self.model.getSquareLength() * 100 * dpi / 2.54) for d in self.model.getChessboardSize()] # 1 cm = 2.54 inches - cv.imwrite(f'{destination_folder}/{output_filename}', self.__board.generateImage(dimension)) + cv.imwrite(f'{destination_folder}/{output_filename}', self.model.generateImage(dimension)) -- cgit v1.1