From 05f5f39c93c989abfdceaff80972b16b2c55a944 Mon Sep 17 00:00:00 2001 From: Théo de la Hogue Date: Wed, 6 Sep 2023 07:31:10 +0200 Subject: Renaming MiscFeatures into UtilsFeatures. Removing useless utils scripts. --- src/argaze.test/GazeAnalysis/Entropy.py | 4 +- .../GazeAnalysis/ExploitExploreRatio.py | 4 +- src/argaze.test/GazeAnalysis/KCoefficient.py | 4 +- .../GazeAnalysis/LempelZivComplexity.py | 4 +- src/argaze.test/GazeAnalysis/NGram.py | 4 +- .../GazeAnalysis/NearestNeighborIndex.py | 4 +- src/argaze.test/GazeAnalysis/TransitionMatrix.py | 4 +- src/argaze/utils/MiscFeatures.py | 148 --------------------- src/argaze/utils/UtilsFeatures.py | 148 +++++++++++++++++++++ src/argaze/utils/__init__.py | 2 +- src/argaze/utils/aruco_calibration_board_export.py | 45 ------- .../utils/aruco_markers_dictionary_export.py | 39 ------ src/argaze/utils/aruco_markers_scene_export.py | 4 +- src/argaze/utils/camera_calibrate.py | 130 ------------------ 14 files changed, 165 insertions(+), 379 deletions(-) delete mode 100644 src/argaze/utils/MiscFeatures.py create mode 100644 src/argaze/utils/UtilsFeatures.py delete mode 100644 src/argaze/utils/aruco_calibration_board_export.py delete mode 100644 src/argaze/utils/aruco_markers_dictionary_export.py delete mode 100644 src/argaze/utils/camera_calibrate.py diff --git a/src/argaze.test/GazeAnalysis/Entropy.py b/src/argaze.test/GazeAnalysis/Entropy.py index f84eca0..ee634d4 100644 --- a/src/argaze.test/GazeAnalysis/Entropy.py +++ b/src/argaze.test/GazeAnalysis/Entropy.py @@ -11,9 +11,9 @@ import unittest from argaze import GazeFeatures from argaze.GazeAnalysis import Entropy, TransitionMatrix -from argaze.utils import MiscFeatures +from argaze.utils import UtilsFeatures -GazeFeaturesTest = MiscFeatures.importFromTestPackage('GazeFeatures') +GazeFeaturesTest = UtilsFeatures.importFromTestPackage('GazeFeatures') class TestAOIScanPathAnalyzer(unittest.TestCase): """Test AOIScanPathAnalyzer class.""" diff --git a/src/argaze.test/GazeAnalysis/ExploitExploreRatio.py b/src/argaze.test/GazeAnalysis/ExploitExploreRatio.py index d788a42..0e6b74a 100644 --- a/src/argaze.test/GazeAnalysis/ExploitExploreRatio.py +++ b/src/argaze.test/GazeAnalysis/ExploitExploreRatio.py @@ -11,9 +11,9 @@ import unittest from argaze import GazeFeatures from argaze.GazeAnalysis import ExploitExploreRatio -from argaze.utils import MiscFeatures +from argaze.utils import UtilsFeatures -GazeFeaturesTest = MiscFeatures.importFromTestPackage('GazeFeatures') +GazeFeaturesTest = UtilsFeatures.importFromTestPackage('GazeFeatures') class TestScanPathAnalyzer(unittest.TestCase): """Test ScanPathAnalyzer class.""" diff --git a/src/argaze.test/GazeAnalysis/KCoefficient.py b/src/argaze.test/GazeAnalysis/KCoefficient.py index a45d3e4..beaeac3 100644 --- a/src/argaze.test/GazeAnalysis/KCoefficient.py +++ b/src/argaze.test/GazeAnalysis/KCoefficient.py @@ -11,9 +11,9 @@ import unittest from argaze import GazeFeatures from argaze.GazeAnalysis import KCoefficient -from argaze.utils import MiscFeatures +from argaze.utils import UtilsFeatures -GazeFeaturesTest = MiscFeatures.importFromTestPackage('GazeFeatures') +GazeFeaturesTest = UtilsFeatures.importFromTestPackage('GazeFeatures') class TestScanPathAnalyzer(unittest.TestCase): """Test ScanPathAnalyzer class.""" diff --git a/src/argaze.test/GazeAnalysis/LempelZivComplexity.py b/src/argaze.test/GazeAnalysis/LempelZivComplexity.py index 9f5ec84..1fdc581 100644 --- a/src/argaze.test/GazeAnalysis/LempelZivComplexity.py +++ b/src/argaze.test/GazeAnalysis/LempelZivComplexity.py @@ -11,9 +11,9 @@ import unittest from argaze import GazeFeatures from argaze.GazeAnalysis import LempelZivComplexity -from argaze.utils import MiscFeatures +from argaze.utils import UtilsFeatures -GazeFeaturesTest = MiscFeatures.importFromTestPackage('GazeFeatures') +GazeFeaturesTest = UtilsFeatures.importFromTestPackage('GazeFeatures') class TestAOIScanPathAnalyzer(unittest.TestCase): """Test AOIScanPathAnalyzer class.""" diff --git a/src/argaze.test/GazeAnalysis/NGram.py b/src/argaze.test/GazeAnalysis/NGram.py index 15e1319..a60cd64 100644 --- a/src/argaze.test/GazeAnalysis/NGram.py +++ b/src/argaze.test/GazeAnalysis/NGram.py @@ -11,9 +11,9 @@ import unittest from argaze import GazeFeatures from argaze.GazeAnalysis import NGram -from argaze.utils import MiscFeatures +from argaze.utils import UtilsFeatures -GazeFeaturesTest = MiscFeatures.importFromTestPackage('GazeFeatures') +GazeFeaturesTest = UtilsFeatures.importFromTestPackage('GazeFeatures') class TestAOIScanPathAnalyzer(unittest.TestCase): """Test AOIScanPathAnalyzer class.""" diff --git a/src/argaze.test/GazeAnalysis/NearestNeighborIndex.py b/src/argaze.test/GazeAnalysis/NearestNeighborIndex.py index c434e1e..b682f29 100644 --- a/src/argaze.test/GazeAnalysis/NearestNeighborIndex.py +++ b/src/argaze.test/GazeAnalysis/NearestNeighborIndex.py @@ -11,9 +11,9 @@ import unittest from argaze import GazeFeatures from argaze.GazeAnalysis import NearestNeighborIndex -from argaze.utils import MiscFeatures +from argaze.utils import UtilsFeatures -GazeFeaturesTest = MiscFeatures.importFromTestPackage('GazeFeatures') +GazeFeaturesTest = UtilsFeatures.importFromTestPackage('GazeFeatures') class TestScanPathAnalyzer(unittest.TestCase): """Test ScanPathAnalyzer class.""" diff --git a/src/argaze.test/GazeAnalysis/TransitionMatrix.py b/src/argaze.test/GazeAnalysis/TransitionMatrix.py index 9a2f4e7..80fbd00 100644 --- a/src/argaze.test/GazeAnalysis/TransitionMatrix.py +++ b/src/argaze.test/GazeAnalysis/TransitionMatrix.py @@ -11,9 +11,9 @@ import unittest from argaze import GazeFeatures from argaze.GazeAnalysis import TransitionMatrix -from argaze.utils import MiscFeatures +from argaze.utils import UtilsFeatures -GazeFeaturesTest = MiscFeatures.importFromTestPackage('GazeFeatures') +GazeFeaturesTest = UtilsFeatures.importFromTestPackage('GazeFeatures') class TestAOIScanPathAnalyzer(unittest.TestCase): """Test AOIScanPathAnalyzer class.""" diff --git a/src/argaze/utils/MiscFeatures.py b/src/argaze/utils/MiscFeatures.py deleted file mode 100644 index 7971167..0000000 --- a/src/argaze/utils/MiscFeatures.py +++ /dev/null @@ -1,148 +0,0 @@ -#!/usr/bin/env python - -"""Miscellaneous class and functions used in utils script.""" - -__author__ = "Théo de la Hogue" -__credits__ = [] -__copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)" -__license__ = "BSD" - -from typing import Tuple -import time -import types - -def printProgressBar (iteration:int, total:int, prefix:str = '', suffix:str = '', decimals:int = 1, length:int = 100, fill:str = '█', printEnd:str = "\r"): - """ - Print iterations progress. - Call in a loop to create terminal progress bar. - - Parameters: - iteration: current iteration - total: total iterations - prefix: string to print before progress bar - suffix: string to print after progress bar - decimals: positive number of decimals in percent complete - length: character length of bar - fill: bar fill character - printEnd: end character (e.g. \\r, \\r\\n) - """ - percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total))) - filledLength = int(length * iteration // total) - bar = fill * filledLength + '-' * (length - filledLength) - print(f'\r{prefix} |{bar}| {percent}% {suffix}', end = printEnd) - - # Print New Line on Complete - if iteration == total: - print() - -def importFromTestPackage(module: str) -> types.ModuleType: - """ - Import module from ArGaze test package. - - Parameters: - module: module name into ArGaze package - - Returns: - module named Test - """ - - import argaze - import importlib.util - import sys - import os - - source_directory = os.path.dirname(os.path.dirname(os.path.abspath(argaze.__file__))) - module_directory = os.path.join(source_directory, 'argaze.test', f'{module}.py') - - spec = importlib.util.spec_from_file_location(f'{module}Test', module_directory) - TestModule = importlib.util.module_from_spec(spec) - sys.modules[f'{module}Test'] = TestModule - spec.loader.exec_module(TestModule) - - return TestModule - -class ExitSignalHandler(): - """ - Handle exit event - """ - - def __init__(self): - - import signal - import threading - - global __exit_event - global __on_exit_signal - - __exit_event = threading.Event() - - def __on_exit_signal(signo, _frame): - __exit_event.set() - - for sig in ('TERM', 'HUP', 'INT'): - signal.signal(getattr(signal, 'SIG'+sig), __on_exit_signal) - - def status(self) -> bool: - """ - Get exit status. - - Returns: - exit status - """ - return __exit_event.is_set() - -class TimeProbe(): - """ - Assess temporal performance. - """ - - def __init__(self): - - self.start() - - def start(self): - """ - Start chronometer. - """ - - self.__last_time = time.perf_counter() - self.__lap_counter = 0 - self.__elapsed_time = 0 - - def lap(self) -> Tuple[float, int, float]: - """ - Get lap info. - - Returns: - last lap time (millisecond) - number of laps - total elapsed time (millisecond) - """ - - lap_time = time.perf_counter() - self.__last_time - - self.__last_time = time.perf_counter() - self.__lap_counter += 1 - self.__elapsed_time += lap_time - - return lap_time * 1e3, self.__lap_counter, self.__elapsed_time * 1e3 - - def end(self) -> float: - """ - Stop chronometer - - Returns: - elapsed time (millisecond) - """ - - self.__elapsed_time += time.perf_counter() - self.__last_time - - return self.__elapsed_time * 1e3, self.__lap_counter - - def restart(self): - """ - Restart chronometer. - """ - - self.start() - diff --git a/src/argaze/utils/UtilsFeatures.py b/src/argaze/utils/UtilsFeatures.py new file mode 100644 index 0000000..7971167 --- /dev/null +++ b/src/argaze/utils/UtilsFeatures.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python + +"""Miscellaneous class and functions used in utils script.""" + +__author__ = "Théo de la Hogue" +__credits__ = [] +__copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)" +__license__ = "BSD" + +from typing import Tuple +import time +import types + +def printProgressBar (iteration:int, total:int, prefix:str = '', suffix:str = '', decimals:int = 1, length:int = 100, fill:str = '█', printEnd:str = "\r"): + """ + Print iterations progress. + Call in a loop to create terminal progress bar. + + Parameters: + iteration: current iteration + total: total iterations + prefix: string to print before progress bar + suffix: string to print after progress bar + decimals: positive number of decimals in percent complete + length: character length of bar + fill: bar fill character + printEnd: end character (e.g. \\r, \\r\\n) + """ + percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total))) + filledLength = int(length * iteration // total) + bar = fill * filledLength + '-' * (length - filledLength) + print(f'\r{prefix} |{bar}| {percent}% {suffix}', end = printEnd) + + # Print New Line on Complete + if iteration == total: + print() + +def importFromTestPackage(module: str) -> types.ModuleType: + """ + Import module from ArGaze test package. + + Parameters: + module: module name into ArGaze package + + Returns: + module named Test + """ + + import argaze + import importlib.util + import sys + import os + + source_directory = os.path.dirname(os.path.dirname(os.path.abspath(argaze.__file__))) + module_directory = os.path.join(source_directory, 'argaze.test', f'{module}.py') + + spec = importlib.util.spec_from_file_location(f'{module}Test', module_directory) + TestModule = importlib.util.module_from_spec(spec) + sys.modules[f'{module}Test'] = TestModule + spec.loader.exec_module(TestModule) + + return TestModule + +class ExitSignalHandler(): + """ + Handle exit event + """ + + def __init__(self): + + import signal + import threading + + global __exit_event + global __on_exit_signal + + __exit_event = threading.Event() + + def __on_exit_signal(signo, _frame): + __exit_event.set() + + for sig in ('TERM', 'HUP', 'INT'): + signal.signal(getattr(signal, 'SIG'+sig), __on_exit_signal) + + def status(self) -> bool: + """ + Get exit status. + + Returns: + exit status + """ + return __exit_event.is_set() + +class TimeProbe(): + """ + Assess temporal performance. + """ + + def __init__(self): + + self.start() + + def start(self): + """ + Start chronometer. + """ + + self.__last_time = time.perf_counter() + self.__lap_counter = 0 + self.__elapsed_time = 0 + + def lap(self) -> Tuple[float, int, float]: + """ + Get lap info. + + Returns: + last lap time (millisecond) + number of laps + total elapsed time (millisecond) + """ + + lap_time = time.perf_counter() - self.__last_time + + self.__last_time = time.perf_counter() + self.__lap_counter += 1 + self.__elapsed_time += lap_time + + return lap_time * 1e3, self.__lap_counter, self.__elapsed_time * 1e3 + + def end(self) -> float: + """ + Stop chronometer + + Returns: + elapsed time (millisecond) + """ + + self.__elapsed_time += time.perf_counter() - self.__last_time + + return self.__elapsed_time * 1e3, self.__lap_counter + + def restart(self): + """ + Restart chronometer. + """ + + self.start() + diff --git a/src/argaze/utils/__init__.py b/src/argaze/utils/__init__.py index 94deb78..0303fbc 100644 --- a/src/argaze/utils/__init__.py +++ b/src/argaze/utils/__init__.py @@ -1,4 +1,4 @@ """ Collection of command-line high level features scripts. """ -__all__ = ['MiscFeatures'] \ No newline at end of file +__all__ = ['UtilsFeatures'] \ No newline at end of file diff --git a/src/argaze/utils/aruco_calibration_board_export.py b/src/argaze/utils/aruco_calibration_board_export.py deleted file mode 100644 index 0bf4454..0000000 --- a/src/argaze/utils/aruco_calibration_board_export.py +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env python - -""" """ - -__author__ = "Théo de la Hogue" -__credits__ = [] -__copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)" -__license__ = "BSD" - -import argparse -import os - -from argaze.ArUcoMarkers import ArUcoMarkersDictionary, ArUcoBoard - -def main(): - """Generates ArUco board to calibrate a camera.""" - - # Manage arguments - parser = argparse.ArgumentParser(description=main.__doc__) - parser.add_argument('columns', metavar='COLS_NUMBER', type=int, default=7, help='number of columns') - parser.add_argument('rows', metavar='ROWS_NUMBER', type=int, default=5, help='number of rows') - parser.add_argument('square_size', metavar='SQUARE_SIZE', type=int, default=5, help='square size in cm') - parser.add_argument('marker_size', metavar='MARKER_SIZE', type=int, default=3, help='marker size in cm') - parser.add_argument('dictionary', metavar='DICTIONARY', type=ArUcoMarkersDictionary.ArUcoMarkersDictionary, default='DICT_ARUCO_ORIGINAL', help='dictionnary name: 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('-o', '--output', metavar='OUT', type=str, default='.', help='destination folder path') - args = parser.parse_args() - - # Manage destination folder - if not os.path.exists(args.output): - os.makedirs(args.output) - print(f'{args.output} folder created') - - # Create aruco board - aruco_board = ArUcoBoard.ArUcoBoard(args.columns, args.rows, args.square_size, args.marker_size, args.dictionary) - - # Export aruco board as png - filepath = f'{args.output}/{aruco_board.dictionary.name}_{aruco_board.marker_size}cm_{aruco_board.columns*aruco_board.square_size}cmx{aruco_board.rows*aruco_board.square_size}cm.png' - aruco_board.save(filepath, args.resolution) - - print(f'{args.columns} x {args.rows} calibration board with {args.marker_size} cm markers from {args.dictionary.name} dictionary exported into {args.output} folder.') - -if __name__ == '__main__': - - main() \ No newline at end of file diff --git a/src/argaze/utils/aruco_markers_dictionary_export.py b/src/argaze/utils/aruco_markers_dictionary_export.py deleted file mode 100644 index d960686..0000000 --- a/src/argaze/utils/aruco_markers_dictionary_export.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env python - -""" """ - -__author__ = "Théo de la Hogue" -__credits__ = [] -__copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)" -__license__ = "BSD" - -import argparse -import os - -from argaze.ArUcoMarkers import ArUcoMarkersDictionary - -def main(): - """Generates all ArUco markers from a given dictionary.""" - - # Manage arguments - parser = argparse.ArgumentParser(description=main.__doc__) - parser.add_argument('dictionary', metavar='DICTIONARY', type=ArUcoMarkersDictionary.ArUcoMarkersDictionary, default='DICT_ARUCO_ORIGINAL', help='dictionnary name: 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('-s', '--size', metavar='SIZE', type=float, default=3., help='marker picture size in cm') - parser.add_argument('-r', '--resolution', metavar='RES', type=int, default=300, help='marker picture resolution in dpi') - parser.add_argument('-o', '--output', metavar='OUT', type=str, default='.', help='destination folder path') - - args = parser.parse_args() - - # Manage destination folder - if not os.path.exists(args.output): - os.makedirs(args.output) - print(f'{args.output} folder created.') - - # Export markers - args.dictionary.save(args.output, args.size, args.resolution) - - print(f'{args.dictionary.number} markers from {args.dictionary.name} dictionary exported into {args.output} folder.') - -if __name__ == '__main__': - - main() \ No newline at end of file diff --git a/src/argaze/utils/aruco_markers_scene_export.py b/src/argaze/utils/aruco_markers_scene_export.py index c1a0991..7f3610f 100644 --- a/src/argaze/utils/aruco_markers_scene_export.py +++ b/src/argaze/utils/aruco_markers_scene_export.py @@ -12,7 +12,7 @@ import time import itertools from argaze.ArUcoMarkers import ArUcoMarkersDictionary, ArUcoOpticCalibrator, ArUcoDetector, ArUcoMarkersGroup -from argaze.utils import MiscFeatures +from argaze.utils import UtilsFeatures import cv2 import numpy @@ -61,7 +61,7 @@ def main(): cv2.namedWindow(window_name, cv2.WINDOW_AUTOSIZE) # Enable exit signal handler - exit = MiscFeatures.ExitSignalHandler() + exit = UtilsFeatures.ExitSignalHandler() # Init image selection current_image_index = -1 diff --git a/src/argaze/utils/camera_calibrate.py b/src/argaze/utils/camera_calibrate.py deleted file mode 100644 index 8b3249b..0000000 --- a/src/argaze/utils/camera_calibrate.py +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env python - -""" """ - -__author__ = "Théo de la Hogue" -__credits__ = [] -__copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)" -__license__ = "BSD" - -import argparse -import os -import time - -from argaze.ArUcoMarkers import ArUcoMarkersDictionary, ArUcoBoard, ArUcoDetector, ArUcoOpticCalibrator - -import cv2 - -def main(): - """ - Captures board pictures and finally outputs optic parameter into a calibration.json file. - - - Export and print a calibration board using aruco_calibration_board_export.py script. - - Place the calibration board face to the camera. - - Move the calibration board in a manner to view it entirely on screen in various configurations (orientation and distance): - The script will automatically take pictures. Do this step with a good lighting and a clear background. - - Once enough pictures have been captured (~20), press Esc key then, wait for optic parameters processing. - - Finally, check rms parameter: it should be between 0. and 1. if the calibration succeeded (lower is better). - - ### Reference: - - [Optic calibration using ArUco marker tutorial](https://automaticaddison.com/how-to-perform-camera-calibration-using-opencv/) - """ - - # Manage arguments - parser = argparse.ArgumentParser(description=main.__doc__.split('-')[0]) - parser.add_argument('columns', metavar='COLS_NUMBER', type=int, default=7, help='expected board columns number') - parser.add_argument('rows', metavar='ROWS_NUMBER', type=int, default=5, help='expected board rows number') - parser.add_argument('square_size', metavar='SQUARE_SIZE', type=float, default=5, help='expected square size in cm') - parser.add_argument('marker_size', metavar='MARKER_SIZE', type=float, default=3, help='expected marker size in cm') - parser.add_argument('dictionary', metavar='DICTIONARY', type=ArUcoMarkersDictionary.ArUcoMarkersDictionary, default='DICT_ARUCO_ORIGINAL', help='expected dictionary name: 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('-d', '--device', metavar='DEVICE', type=int, default=0, help='video capture device id') - parser.add_argument('-o', '--output', metavar='OUT', type=str, default='.', help='destination folder filepath') - args = parser.parse_args() - - # Enable camera video capture - video_capture = cv2.VideoCapture(args.device) - - image_width = int(video_capture.get(cv2.CAP_PROP_FRAME_WIDTH)) - image_height = int(video_capture.get(cv2.CAP_PROP_FRAME_HEIGHT)) - - # Create aruco optic calibrator - aruco_optic_calibrator = ArUcoOpticCalibrator.ArUcoOpticCalibrator() - - # Create aruco board - aruco_board = ArUcoBoard.ArUcoBoard(args.columns, args.rows, args.square_size, args.marker_size, args.dictionary) - - # Create aruco detector - aruco_detector = ArUcoDetector.ArUcoDetector(dictionary=args.dictionary, marker_size=args.marker_size) - - print(f'{image_width}x{image_height} pixels camera calibration starts') - print("Waiting for calibration board...") - - expected_markers_number = aruco_board.markers_number - expected_corners_number = aruco_board.corners_number - - # Capture loop - try: - - # Capture images with a full displayed board inside - while video_capture.isOpened(): - - success, video_image = video_capture.read() - - if success: - - # Detect calibration board - aruco_detector.detect_board(video_image, aruco_board, expected_markers_number) - - # Draw detected markers - aruco_detector.draw_detected_markers(video_image) - - # Draw current calibration data count - cv2.putText(video_image, f'Capture: {aruco_optic_calibrator.calibration_data_count}', (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv2.LINE_AA) - cv2.imshow('Optic Calibration', video_image) - - # If all board corners are detected - if aruco_detector.board_corners_number == expected_corners_number: - - # Draw board corners to notify a capture is done - aruco_detector.draw_board(video_image) - - # Append calibration data - aruco_optic_calibrator.store_calibration_data(aruco_detector.board_corners, aruco_detector.board_corners_identifier) - - cv2.imshow('Optic Calibration', video_image) - - # Stop calibration by pressing 'Esc' key - if cv2.waitKey(1) == 27: - break - - # Stop calibration on 'ctrl+C' interruption - except KeyboardInterrupt: - pass - - # Stop image display - cv2.destroyAllWindows() - - print('\nCalibrating camera...') - optic_parameters = aruco_optic_calibrator.calibrate(aruco_board, dimensions=(image_width, image_height)) - - if optic_parameters: - - print('\nCalibration succeeded!') - - print(f'\nRMS:\n{optic_parameters.rms}') - print(f'\nDimensions:\n{optic_parameters.dimensions[0]}x{optic_parameters.dimensions[1]}') - print(f'\nCamera matrix:\n{optic_parameters.K}') - print(f'\nDistortion coefficients:\n{optic_parameters.D}') - - optic_parameters.to_json(f'{args.output}/optic_parameters.json') - - print(f'\ncalibration.json file exported into {args.output} folder') - - else: - - print('\nCalibration error.') - -if __name__ == '__main__': - - main() -- cgit v1.1