From 4d0de7c804914a55977635ec6bc46beb0cf7808a Mon Sep 17 00:00:00 2001 From: Théo de la Hogue Date: Wed, 17 Apr 2024 13:32:51 +0200 Subject: Renaming ArUcoMarkers into ArUcoMarker --- src/argaze.test/ArUcoMarker/ArUcoBoard.py | 50 +++++ src/argaze.test/ArUcoMarker/ArUcoCamera.py | 80 ++++++++ src/argaze.test/ArUcoMarker/ArUcoDetector.py | 149 ++++++++++++++ src/argaze.test/ArUcoMarker/ArUcoMarker.py | 40 ++++ .../ArUcoMarker/ArUcoMarkerDictionary.py | 50 +++++ .../ArUcoMarker/ArUcoOpticCalibrator.py | 61 ++++++ src/argaze.test/ArUcoMarker/ArUcoScene.py | 227 +++++++++++++++++++++ src/argaze.test/ArUcoMarker/__init__.py | 0 src/argaze.test/ArUcoMarker/utils/aoi_3d.obj | 7 + .../ArUcoMarker/utils/aruco_camera.json | 98 +++++++++ src/argaze.test/ArUcoMarker/utils/detector.json | 42 ++++ .../ArUcoMarker/utils/detector_parameters.json | 5 + .../ArUcoMarker/utils/full_hd_board.png | Bin 0 -> 18475 bytes .../ArUcoMarker/utils/full_hd_marker.png | Bin 0 -> 116210 bytes .../ArUcoMarker/utils/optic_parameters.json | 31 +++ src/argaze.test/ArUcoMarker/utils/scene.json | 20 ++ src/argaze.test/ArUcoMarker/utils/scene.obj | 22 ++ src/argaze.test/ArUcoMarkers/ArUcoBoard.py | 50 ----- src/argaze.test/ArUcoMarkers/ArUcoCamera.py | 80 -------- src/argaze.test/ArUcoMarkers/ArUcoDetector.py | 149 -------------- src/argaze.test/ArUcoMarkers/ArUcoMarker.py | 40 ---- .../ArUcoMarkers/ArUcoMarkersDictionary.py | 50 ----- .../ArUcoMarkers/ArUcoOpticCalibrator.py | 61 ------ src/argaze.test/ArUcoMarkers/ArUcoScene.py | 227 --------------------- src/argaze.test/ArUcoMarkers/__init__.py | 0 src/argaze.test/ArUcoMarkers/utils/aoi_3d.obj | 7 - .../ArUcoMarkers/utils/aruco_camera.json | 98 --------- src/argaze.test/ArUcoMarkers/utils/detector.json | 42 ---- .../ArUcoMarkers/utils/detector_parameters.json | 5 - .../ArUcoMarkers/utils/full_hd_board.png | Bin 18475 -> 0 bytes .../ArUcoMarkers/utils/full_hd_marker.png | Bin 116210 -> 0 bytes .../ArUcoMarkers/utils/optic_parameters.json | 31 --- src/argaze.test/ArUcoMarkers/utils/scene.json | 20 -- src/argaze.test/ArUcoMarkers/utils/scene.obj | 22 -- 34 files changed, 882 insertions(+), 882 deletions(-) create mode 100644 src/argaze.test/ArUcoMarker/ArUcoBoard.py create mode 100644 src/argaze.test/ArUcoMarker/ArUcoCamera.py create mode 100644 src/argaze.test/ArUcoMarker/ArUcoDetector.py create mode 100644 src/argaze.test/ArUcoMarker/ArUcoMarker.py create mode 100644 src/argaze.test/ArUcoMarker/ArUcoMarkerDictionary.py create mode 100644 src/argaze.test/ArUcoMarker/ArUcoOpticCalibrator.py create mode 100644 src/argaze.test/ArUcoMarker/ArUcoScene.py create mode 100644 src/argaze.test/ArUcoMarker/__init__.py create mode 100644 src/argaze.test/ArUcoMarker/utils/aoi_3d.obj create mode 100644 src/argaze.test/ArUcoMarker/utils/aruco_camera.json create mode 100644 src/argaze.test/ArUcoMarker/utils/detector.json create mode 100644 src/argaze.test/ArUcoMarker/utils/detector_parameters.json create mode 100644 src/argaze.test/ArUcoMarker/utils/full_hd_board.png create mode 100644 src/argaze.test/ArUcoMarker/utils/full_hd_marker.png create mode 100644 src/argaze.test/ArUcoMarker/utils/optic_parameters.json create mode 100644 src/argaze.test/ArUcoMarker/utils/scene.json create mode 100644 src/argaze.test/ArUcoMarker/utils/scene.obj delete mode 100644 src/argaze.test/ArUcoMarkers/ArUcoBoard.py delete mode 100644 src/argaze.test/ArUcoMarkers/ArUcoCamera.py delete mode 100644 src/argaze.test/ArUcoMarkers/ArUcoDetector.py delete mode 100644 src/argaze.test/ArUcoMarkers/ArUcoMarker.py delete mode 100644 src/argaze.test/ArUcoMarkers/ArUcoMarkersDictionary.py delete mode 100644 src/argaze.test/ArUcoMarkers/ArUcoOpticCalibrator.py delete mode 100644 src/argaze.test/ArUcoMarkers/ArUcoScene.py delete mode 100644 src/argaze.test/ArUcoMarkers/__init__.py delete mode 100644 src/argaze.test/ArUcoMarkers/utils/aoi_3d.obj delete mode 100644 src/argaze.test/ArUcoMarkers/utils/aruco_camera.json delete mode 100644 src/argaze.test/ArUcoMarkers/utils/detector.json delete mode 100644 src/argaze.test/ArUcoMarkers/utils/detector_parameters.json delete mode 100644 src/argaze.test/ArUcoMarkers/utils/full_hd_board.png delete mode 100644 src/argaze.test/ArUcoMarkers/utils/full_hd_marker.png delete mode 100644 src/argaze.test/ArUcoMarkers/utils/optic_parameters.json delete mode 100644 src/argaze.test/ArUcoMarkers/utils/scene.json delete mode 100644 src/argaze.test/ArUcoMarkers/utils/scene.obj (limited to 'src/argaze.test') diff --git a/src/argaze.test/ArUcoMarker/ArUcoBoard.py b/src/argaze.test/ArUcoMarker/ArUcoBoard.py new file mode 100644 index 0000000..b20be13 --- /dev/null +++ b/src/argaze.test/ArUcoMarker/ArUcoBoard.py @@ -0,0 +1,50 @@ +""" + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +__author__ = "Théo de la Hogue" +__credits__ = [] +__copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)" +__license__ = "GPLv3" + +import unittest +import os + +from argaze.ArUcoMarker import ArUcoBoard, ArUcoMarkerDictionary + +import numpy + +class TestArUcoBoardClass(unittest.TestCase): + """Test ArUcoBoard class.""" + + def test_new(self): + """Test ArUcoBoard creation using a dictionary instance.""" + + columns = 4 + rows = 3 + square_size = 2 + marker_size = 1 + + # Check ArUco board creation + aruco_dictionary = ArUcoMarkerDictionary.ArUcoMarkerDictionary('DICT_APRILTAG_16h5') + 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') + 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__': + + unittest.main() \ No newline at end of file diff --git a/src/argaze.test/ArUcoMarker/ArUcoCamera.py b/src/argaze.test/ArUcoMarker/ArUcoCamera.py new file mode 100644 index 0000000..eb930ab --- /dev/null +++ b/src/argaze.test/ArUcoMarker/ArUcoCamera.py @@ -0,0 +1,80 @@ +""" + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +__author__ = "Théo de la Hogue" +__credits__ = [] +__copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)" +__license__ = "GPLv3" + +import unittest +import os + +import argaze + +import numpy + +class TestArUcoCameraClass(unittest.TestCase): + """Test ArUcoCamera class.""" + + def test_from_json(self): + """Test ArUcoCamera creation from json file.""" + + # Edit test aruco camera file path + current_directory = os.path.dirname(os.path.abspath(__file__)) + json_filepath = os.path.join(current_directory, 'utils/aruco_camera.json') + + # Load test aruco camera + with argaze.load(json_filepath) as aruco_camera: + + # Check aruco camera meta data + self.assertEqual(aruco_camera.name, "TestArUcoCamera") + + # Check ArUco detector + self.assertEqual(aruco_camera.aruco_detector.dictionary.name, "DICT_ARUCO_ORIGINAL") + self.assertEqual(aruco_camera.aruco_detector.parameters.cornerRefinementMethod, 3) + self.assertEqual(aruco_camera.aruco_detector.parameters.aprilTagQuadSigma, 2) + self.assertEqual(aruco_camera.aruco_detector.parameters.aprilTagDeglitch, 1) + + # Check ArUco detector optic parameters + self.assertEqual(aruco_camera.aruco_detector.optic_parameters.rms, 1.0) + self.assertIsNone(numpy.testing.assert_array_equal(aruco_camera.aruco_detector.optic_parameters.dimensions, [1920, 1080])) + self.assertIsNone(numpy.testing.assert_array_equal(aruco_camera.aruco_detector.optic_parameters.K, [[1.0, 0.0, 1.0], [0.0, 1.0, 1.0], [0.0, 0.0, 1.0]])) + self.assertIsNone(numpy.testing.assert_array_equal(aruco_camera.aruco_detector.optic_parameters.D, [-1.0, -0.5, 0.0, 0.5, 1.0])) + + # Check camera scenes + self.assertEqual(len(aruco_camera.scenes), 2) + self.assertIsNone(numpy.testing.assert_array_equal(list(aruco_camera.scenes.keys()), ["TestSceneA", "TestSceneB"])) + + # Load test scene + ar_scene = aruco_camera.scenes["TestSceneA"] + + # Check Aruco scene + self.assertEqual(len(ar_scene.aruco_markers_group.places), 2) + self.assertIsNone(numpy.testing.assert_allclose(ar_scene.aruco_markers_group.places[0].corners[0], [-0.5, 1.5, 0.], rtol=0, atol=1e-3)) + self.assertEqual(ar_scene.aruco_markers_group.places[0].marker.identifier, 0) + + self.assertIsNone(numpy.testing.assert_allclose(ar_scene.aruco_markers_group.places[1].corners[0], [0., 2.5, -1.5], rtol=0, atol=1e-3)) + self.assertEqual(ar_scene.aruco_markers_group.places[1].marker.identifier, 1) + + # Check layers and AOI scene + self.assertEqual(len(ar_scene.layers.items()), 1) + self.assertEqual(len(ar_scene.layers["Main"].aoi_scene), 1) + self.assertEqual(ar_scene.layers["Main"].aoi_scene['Test'].points_number, 4) + + # Check ArScene + self.assertEqual(ar_scene.angle_tolerance, 1.0) + self.assertEqual(ar_scene.distance_tolerance, 2.0) + +if __name__ == '__main__': + + unittest.main() \ No newline at end of file diff --git a/src/argaze.test/ArUcoMarker/ArUcoDetector.py b/src/argaze.test/ArUcoMarker/ArUcoDetector.py new file mode 100644 index 0000000..40b7d00 --- /dev/null +++ b/src/argaze.test/ArUcoMarker/ArUcoDetector.py @@ -0,0 +1,149 @@ +""" + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +__author__ = "Théo de la Hogue" +__credits__ = [] +__copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)" +__license__ = "GPLv3" + +import unittest +import os +import math + +from argaze.ArUcoMarker import ArUcoMarkerDictionary, ArUcoOpticCalibrator, ArUcoDetector, ArUcoBoard + +import cv2 as cv +import numpy + +class TestDetectorParametersClass(unittest.TestCase): + """Test DetectorParameters class.""" + + def test_from_json(self): + """Test DetectorParameters creation from json file.""" + + # Edit file path + current_directory = os.path.dirname(os.path.abspath(__file__)) + json_filepath = os.path.join(current_directory, 'utils/detector_parameters.json') + + # Load file + detector_parameters = ArUcoDetector.DetectorParameters.from_json(json_filepath) + + # Check data + self.assertEqual(detector_parameters.cornerRefinementMethod, 3) + self.assertEqual(detector_parameters.aprilTagQuadSigma, 2) + self.assertEqual(detector_parameters.aprilTagDeglitch, 1) + + # Check bad data access fails + with self.assertRaises(AttributeError): + + detector_parameters.unknown_data = 1 + +class TestArUcoDetectorClass(unittest.TestCase): + """Test ArUcoDetector class.""" + + def test_new(self): + """Test ArUcoDetector creation.""" + + aruco_detector = ArUcoDetector.ArUcoDetector(marker_size=3) + + # Check ArUcoDetector creation + self.assertEqual(aruco_detector.dictionary.name, 'DICT_ARUCO_ORIGINAL') + self.assertEqual(aruco_detector.marker_size, 3) + self.assertIsNone(numpy.testing.assert_array_equal(aruco_detector.optic_parameters.dimensions, [0, 0])) + self.assertEqual(aruco_detector.detected_markers_number(), 0) + self.assertEqual(aruco_detector.detected_markers(), {}) + + aruco_dictionary = ArUcoMarkerDictionary.ArUcoMarkerDictionary('DICT_APRILTAG_16h5') + aruco_detector = ArUcoDetector.ArUcoDetector(aruco_dictionary, 5.2) + + # Check ArUcoDetector creation + self.assertEqual(aruco_detector.dictionary.name, 'DICT_APRILTAG_16h5') + self.assertEqual(aruco_detector.marker_size, 5.2) + self.assertIsNone(numpy.testing.assert_array_equal(aruco_detector.optic_parameters.dimensions, [0, 0])) + self.assertEqual(aruco_detector.detected_markers_number(), 0) + self.assertEqual(aruco_detector.detected_markers(), {}) + + def test_from_json(self): + """Test ArUcoDetector creation.""" + + # Edit file path + current_directory = os.path.dirname(os.path.abspath(__file__)) + json_filepath = os.path.join(current_directory, 'utils/detector.json') + + # Load file + aruco_detector = ArUcoDetector.ArUcoDetector.from_json(json_filepath) + + # Check ArUcoDetector creation + self.assertEqual(aruco_detector.dictionary.name, 'DICT_ARUCO_ORIGINAL') + self.assertEqual(aruco_detector.marker_size, 3) + self.assertIsNone(numpy.testing.assert_array_equal(aruco_detector.optic_parameters.dimensions, [1920, 1080])) + self.assertEqual(aruco_detector.parameters.cornerRefinementMethod, 3) + self.assertEqual(aruco_detector.parameters.aprilTagQuadSigma, 2) + self.assertEqual(aruco_detector.parameters.aprilTagDeglitch, 1) + + def test_detect(self): + """Test detect method.""" + + aruco_detector = ArUcoDetector.ArUcoDetector(marker_size=3) + + # Load picture Full HD to test ArUcoMarker detection + current_directory = os.path.dirname(os.path.abspath(__file__)) + image = cv.imread(os.path.join(current_directory, 'utils/full_hd_marker.png')) + + # Check ArUcoMarker detection + aruco_detector.detect_markers(image) + + self.assertEqual(aruco_detector.detected_markers_number(), 1) + + self.assertEqual(aruco_detector.detected_markers()[0].dictionary, aruco_detector.dictionary) + self.assertEqual(aruco_detector.detected_markers()[0].identifier, 0) + self.assertEqual(aruco_detector.detected_markers()[0].size, 3) + + # Check corner positions with -/+ 10 pixels precision + self.assertIsNone(numpy.testing.assert_almost_equal(aruco_detector.detected_markers()[0].corners[0][0].astype(int), numpy.array([3823, 2073]), decimal=-1)) + self.assertIsNone(numpy.testing.assert_almost_equal(aruco_detector.detected_markers()[0].corners[0][1].astype(int), numpy.array([4177, 2073]), decimal=-1)) + self.assertIsNone(numpy.testing.assert_almost_equal(aruco_detector.detected_markers()[0].corners[0][2].astype(int), numpy.array([4177, 2427]), decimal=-1)) + self.assertIsNone(numpy.testing.assert_almost_equal(aruco_detector.detected_markers()[0].corners[0][3].astype(int), numpy.array([3823, 2427]), decimal=-1)) + + # Check marker pose estimation + aruco_detector.estimate_markers_pose([0]) + + # Check marker translation with -/+ 0.1 cm precision and rotation with -/+ 0.001 radian precision + self.assertIsNone(numpy.testing.assert_almost_equal(aruco_detector.detected_markers()[0].translation, numpy.array([33.87, 19.05, 0.]), decimal=1)) + self.assertIsNone(numpy.testing.assert_almost_equal(aruco_detector.detected_markers()[0].rotation, numpy.array([[1., 0., 0.], [0., -1., 0.], [0., 0., -1.]]), decimal=3)) + + # Check detect metrics + detect_count, markers_count = aruco_detector.detection_metrics + self.assertEqual(detect_count, 1) + self.assertEqual(markers_count[0], 1) + + def test_detect_board(self): + """Test detect board method.""" + + aruco_board = ArUcoBoard.ArUcoBoard(7, 5, 5, 3) + aruco_detector = ArUcoDetector.ArUcoDetector(marker_size=3) + + # Load picture Full HD to test ArUcoMarker board detection + current_directory = os.path.dirname(os.path.abspath(__file__)) + image = cv.imread(os.path.join(current_directory, 'utils/full_hd_board.png')) + + # Check ArUcoMarker board detection + aruco_detector.detect_board(image, aruco_board, aruco_board.markers_number) + + self.assertEqual(aruco_detector.board_corners_number(), aruco_board.corners_number) + self.assertEqual(len(aruco_detector.board_corners()), 24) + self.assertEqual(len(aruco_detector.board_corners_identifier()), 24) + +if __name__ == '__main__': + + unittest.main() \ No newline at end of file diff --git a/src/argaze.test/ArUcoMarker/ArUcoMarker.py b/src/argaze.test/ArUcoMarker/ArUcoMarker.py new file mode 100644 index 0000000..6518c8c --- /dev/null +++ b/src/argaze.test/ArUcoMarker/ArUcoMarker.py @@ -0,0 +1,40 @@ +""" + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +__author__ = "Théo de la Hogue" +__credits__ = [] +__copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)" +__license__ = "GPLv3" + +import unittest + +from argaze.ArUcoMarker import ArUcoMarkerDictionary, ArUcoMarker + +class TestArUcoMarkerClass(unittest.TestCase): + """Test ArUcoMarker class.""" + + def test_new(self): + """Test ArUcoMarker creation.""" + + # Check DICT_ARUCO_ORIGINAL ArUcoMarker creation + aruco_dictionary = ArUcoMarkerDictionary.ArUcoMarkerDictionary('DICT_ARUCO_ORIGINAL') + + aruco_marker = aruco_dictionary.create_marker(0, 3) + + self.assertEqual(aruco_marker.dictionary, aruco_dictionary) + self.assertEqual(aruco_marker.identifier, 0) + self.assertEqual(aruco_marker.size, 3) + +if __name__ == '__main__': + + unittest.main() \ No newline at end of file diff --git a/src/argaze.test/ArUcoMarker/ArUcoMarkerDictionary.py b/src/argaze.test/ArUcoMarker/ArUcoMarkerDictionary.py new file mode 100644 index 0000000..2f80a67 --- /dev/null +++ b/src/argaze.test/ArUcoMarker/ArUcoMarkerDictionary.py @@ -0,0 +1,50 @@ +""" + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +__author__ = "Théo de la Hogue" +__credits__ = [] +__copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)" +__license__ = "GPLv3" + +import unittest + +from argaze.ArUcoMarker import ArUcoMarkerDictionary + +class TestArUcoMarkerDictionaryClass(unittest.TestCase): + """Test ArUcoMarkerDictionary class.""" + + def test_new(self): + """Test ArUcoMarkerDictionary creation.""" + + # Check that ArUcoMarkerDictionary creation fails with bad name + with self.assertRaises(NameError): + + aruco_dictionary = ArUcoMarkerDictionary.ArUcoMarkerDictionary('BAD_DICT_NAME') + + # Check default ArUcoMarkerDictionary creation + aruco_dictionary = ArUcoMarkerDictionary.ArUcoMarkerDictionary() + + self.assertEqual(aruco_dictionary.name, 'DICT_ARUCO_ORIGINAL') + self.assertEqual(aruco_dictionary.format, '5X5') + self.assertEqual(aruco_dictionary.number, 1024) + + # Check DICT_APRILTAG_16h5 ArUcoMarkerDictionary creation + aruco_dictionary = ArUcoMarkerDictionary.ArUcoMarkerDictionary('DICT_APRILTAG_16h5') + + self.assertEqual(aruco_dictionary.name, 'DICT_APRILTAG_16h5') + self.assertEqual(aruco_dictionary.format, '4X4') + self.assertEqual(aruco_dictionary.number, 30) + +if __name__ == '__main__': + + unittest.main() \ No newline at end of file diff --git a/src/argaze.test/ArUcoMarker/ArUcoOpticCalibrator.py b/src/argaze.test/ArUcoMarker/ArUcoOpticCalibrator.py new file mode 100644 index 0000000..d019a5d --- /dev/null +++ b/src/argaze.test/ArUcoMarker/ArUcoOpticCalibrator.py @@ -0,0 +1,61 @@ +""" + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +__author__ = "Théo de la Hogue" +__credits__ = [] +__copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)" +__license__ = "GPLv3" + +import unittest +import os + +from argaze.ArUcoMarker import ArUcoOpticCalibrator + +import numpy + +class TestOpticParametersClass(unittest.TestCase): + """Test OpticParameters class.""" + + def test_new(self): + """Test OpticParameters creation.""" + + # Check defaut optic parameters creation + optic_parameters = ArUcoOpticCalibrator.OpticParameters() + + # Check ArUco optic parameters + self.assertEqual(optic_parameters.rms, 0.0) + + #self.assertEqual(type(optic_parameters.K), numpy.array) + + self.assertIsNone(numpy.testing.assert_array_equal(optic_parameters.dimensions, [0, 0])) + self.assertIsNone(numpy.testing.assert_array_equal(optic_parameters.K, ArUcoOpticCalibrator.K0)) + self.assertIsNone(numpy.testing.assert_array_equal(optic_parameters.D, ArUcoOpticCalibrator.D0)) + + def test_from_json(self): + + # Edit optic parameters file path + current_directory = os.path.dirname(os.path.abspath(__file__)) + json_filepath = os.path.join(current_directory, 'utils/optic_parameters.json') + + # Load optic parameters + optic_parameters = ArUcoOpticCalibrator.OpticParameters.from_json(json_filepath) + + # Check ArUco camera + self.assertEqual(optic_parameters.rms, 1.0) + self.assertIsNone(numpy.testing.assert_array_equal(optic_parameters.dimensions, [1920, 1080])) + self.assertIsNone(numpy.testing.assert_array_equal(optic_parameters.K, [[1.0, 0.0, 1.0], [0.0, 1.0, 1.0], [0.0, 0.0, 1.0]])) + self.assertIsNone(numpy.testing.assert_array_equal(optic_parameters.D, [-1.0, -0.5, 0.0, 0.5, 1.0])) + +if __name__ == '__main__': + + unittest.main() \ No newline at end of file diff --git a/src/argaze.test/ArUcoMarker/ArUcoScene.py b/src/argaze.test/ArUcoMarker/ArUcoScene.py new file mode 100644 index 0000000..67cb668 --- /dev/null +++ b/src/argaze.test/ArUcoMarker/ArUcoScene.py @@ -0,0 +1,227 @@ +""" + +This program is free software: you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +You should have received a copy of the GNU General Public License along with +this program. If not, see . +""" + +__author__ = "Théo de la Hogue" +__credits__ = [] +__copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)" +__license__ = "GPLv3" + +import unittest +import os +import math + +from argaze.ArUcoMarker import ArUcoMarkerGroup, ArUcoMarker + +import cv2 as cv +import numpy + +class TestArUcoMarkerGroupClass(unittest.TestCase): + + def new_from_obj(self): + + # Edit file path + current_directory = os.path.dirname(os.path.abspath(__file__)) + obj_filepath = os.path.join(current_directory, 'utils/scene.obj') + + # Load file + self.aruco_markers_group = ArUcoMarkerGroup.ArUcoMarkerGroup.from_obj(obj_filepath) + + def new_from_json(self): + + # Edit file path + current_directory = os.path.dirname(os.path.abspath(__file__)) + json_filepath = os.path.join(current_directory, 'utils/scene.json') + + # Load file + self.aruco_markers_group = ArUcoMarkerGroup.ArUcoMarkerGroup.from_json(json_filepath) + + def setup_markers(self): + + # Prepare detected markers + self.detected_markers = { + 0: ArUcoMarker.ArUcoMarker('DICT_ARUCO_ORIGINAL', 0, 1.), + 1: ArUcoMarker.ArUcoMarker('DICT_ARUCO_ORIGINAL', 1, 1.), + 2: ArUcoMarker.ArUcoMarker('DICT_ARUCO_ORIGINAL', 2, 1.), + 3: ArUcoMarker.ArUcoMarker('DICT_ARUCO_ORIGINAL', 3, 1.) + } + + # Prepare scene markers and remaining markers + self.scene_markers, self.remaining_markers = self.aruco_markers_group.filter_markers(self.detected_markers()) + + def test_new_from_obj(self): + """Test ArUcoMarkerGroup creation.""" + + self.new_from_obj() + self.setup_markers() + + # Check ArUcoMarkerGroup creation + self.assertEqual(len(self.aruco_markers_group.places), 3) + self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.identifiers, [0, 1, 2])) + self.assertEqual(self.aruco_markers_group.marker_size, 1.) + + self.assertEqual(self.aruco_markers_group.places[0].marker.identifier, 0) + self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[0].translation, [0., 0., 0.])) + self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[0].rotation, [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])) + + self.assertEqual(self.aruco_markers_group.places[1].marker.identifier, 1) + self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[1].translation, [10., 10., 0.])) + self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[1].rotation, [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])) + + self.assertEqual(self.aruco_markers_group.places[2].marker.identifier, 2) + self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[2].translation, [0., 10., 0.])) + self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[2].rotation, [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])) + + def test_new_from_json(self): + """Test ArUcoMarkerGroup creation.""" + + self.new_from_json() + self.setup_markers() + + # Check ArUcoMarkerGroup creation + self.assertEqual(len(self.aruco_markers_group.places), 3) + self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.identifiers, [0, 1, 2])) + self.assertEqual(self.aruco_markers_group.marker_size, 1.) + + self.assertEqual(self.aruco_markers_group.places[0].marker.identifier, 0) + self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[0].translation, [0., 0., 0.])) + self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[0].rotation, [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])) + + self.assertEqual(self.aruco_markers_group.places[1].marker.identifier, 1) + self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[1].translation, [10., 10., 0.])) + self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[1].rotation, [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])) + + self.assertEqual(self.aruco_markers_group.places[2].marker.identifier, 2) + self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[2].translation, [0., 10., 0.])) + self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[2].rotation, [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])) + + def test_filter_markers(self): + """Test ArUcoMarkerGroup markers filtering.""" + + self.new_from_obj() + self.setup_markers() + + # Check scene markers and remaining markers + self.assertEqual(len(self.scene_markers), 3) + self.assertEqual(len(self.remaining_markers), 1) + + self.assertIsNone(numpy.testing.assert_array_equal(list(self.scene_markers.keys()), self.aruco_markers_group.identifiers)) + self.assertIsNone(numpy.testing.assert_array_equal(list(self.remaining_markers.keys()), [3])) + + def test_check_markers_consistency(self): + """Test ArUcoMarkerGroup markers consistency checking.""" + + self.new_from_obj() + self.setup_markers() + + # Edit consistent marker poses + self.scene_markers[0].translation = numpy.array([1., 1., 5.]) + self.scene_markers[0].rotation = numpy.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) + + self.scene_markers[1].translation = numpy.array([11., 11., 5.]) + self.scene_markers[1].rotation = numpy.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) + + self.scene_markers[2].translation = numpy.array([1., 11., 5.]) + self.scene_markers[2].rotation = numpy.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) + + # Check consistency + consistent_markers, unconsistent_markers, unconsistencies = self.aruco_markers_group.check_markers_consistency(self.scene_markers, 1, 1) + + # Check consistent markers, unconsistent markers and unconsistencies + self.assertEqual(len(consistent_markers), 3) + self.assertEqual(len(unconsistent_markers), 0) + self.assertEqual(len(unconsistencies['rotation']), 0) + self.assertEqual(len(unconsistencies['translation']), 0) + + self.assertIsNone(numpy.testing.assert_array_equal(list(consistent_markers.keys()), self.aruco_markers_group.identifiers)) + + # Edit unconsistent marker poses + self.scene_markers[2].translation = numpy.array([5., 15., 5.]) + + # Check consistency + consistent_markers, unconsistent_markers, unconsistencies = self.aruco_markers_group.check_markers_consistency(self.scene_markers, 1, 1) + + # Check consistent markers, unconsistent markers and unconsistencies + self.assertEqual(len(consistent_markers), 2) + self.assertEqual(len(unconsistent_markers), 1) + self.assertEqual(len(unconsistencies['rotation']), 0) + self.assertEqual(len(unconsistencies['translation']), 2) + + self.assertIsNone(numpy.testing.assert_array_equal(list(unconsistent_markers.keys()), [2])) + self.assertIsNone(numpy.testing.assert_array_equal(list(unconsistencies['translation'].keys()), ['0/2', '1/2'])) + self.assertIsNone(numpy.testing.assert_array_equal(list(unconsistencies['translation']['0/2'].keys()), ['current', 'expected'])) + self.assertIsNone(numpy.testing.assert_array_equal(list(unconsistencies['translation']['1/2'].keys()), ['current', 'expected'])) + + def test_estimate_pose_from_single_marker(self): + """Test ArUcoMarkerGroup pose estimation from single marker.""" + + self.new_from_obj() + self.setup_markers() + + # Edit marke pose + self.scene_markers[0].translation = numpy.array([1., 1., 5.]) + self.scene_markers[0].rotation = numpy.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) + + # Estimate pose + tvec, rmat = self.aruco_markers_group.estimate_pose_from_single_marker(self.scene_markers[0]) + + self.assertIsNone(numpy.testing.assert_array_equal(tvec, [1., 1., 5.])) + self.assertIsNone(numpy.testing.assert_array_equal(rmat, [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])) + + def test_estimate_pose_from_markers(self): + """Test ArUcoMarkerGroup pose estimation from markers.""" + + self.new_from_obj() + self.setup_markers() + + # Edit markers pose + self.scene_markers[0].translation = numpy.array([1., 1., 5.]) + self.scene_markers[0].rotation = numpy.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) + + self.scene_markers[1].translation = numpy.array([11., 11., 5.]) + self.scene_markers[1].rotation = numpy.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) + + self.scene_markers[2].translation = numpy.array([1., 11., 5.]) + self.scene_markers[2].rotation = numpy.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) + + # Estimate pose + tvec, rmat = self.aruco_markers_group.estimate_pose_from_markers(self.scene_markers) + + self.assertIsNone(numpy.testing.assert_array_equal(tvec, [1., 1., 5.])) + self.assertIsNone(numpy.testing.assert_array_equal(rmat, [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])) + + @unittest.skip("ArUcoMarkerGroup estimate_pose_from_axis_markers method is broken.") + def test_estimate_pose_from_axis_markers(self): + """Test ArUcoMarkerGroup pose estimation from axis markers.""" + + self.new_from_obj() + self.setup_markers() + + # Edit markers pose + self.scene_markers[0].translation = numpy.array([1., 1., 5.]) + self.scene_markers[0].rotation = numpy.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) + + self.scene_markers[1].translation = numpy.array([11., 11., 5.]) + self.scene_markers[1].rotation = numpy.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) + + self.scene_markers[2].translation = numpy.array([1., 11., 5.]) + self.scene_markers[2].rotation = numpy.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) + + # Estimate pose + tvec, rmat = self.aruco_markers_group.estimate_pose_from_axis_markers(self.scene_markers[2], self.scene_markers[1], self.scene_markers[0]) + + self.assertIsNone(numpy.testing.assert_array_equal(tvec, [1., 1., 5.])) + self.assertIsNone(numpy.testing.assert_array_equal(rmat, [[1., 0., 0.], [0., -1., 0.], [0., 0., -1.]])) + +if __name__ == '__main__': + + unittest.main() \ No newline at end of file diff --git a/src/argaze.test/ArUcoMarker/__init__.py b/src/argaze.test/ArUcoMarker/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/argaze.test/ArUcoMarker/utils/aoi_3d.obj b/src/argaze.test/ArUcoMarker/utils/aoi_3d.obj new file mode 100644 index 0000000..92e85bd --- /dev/null +++ b/src/argaze.test/ArUcoMarker/utils/aoi_3d.obj @@ -0,0 +1,7 @@ +o Test +v 0.000000 0.000000 0.000000 +v 25.000000 0.000000 0.000000 +v 0.000000 14.960000 0.000000 +v 25.000000 14.960000 0.000000 +s off +f 1 2 4 3 diff --git a/src/argaze.test/ArUcoMarker/utils/aruco_camera.json b/src/argaze.test/ArUcoMarker/utils/aruco_camera.json new file mode 100644 index 0000000..980dc9f --- /dev/null +++ b/src/argaze.test/ArUcoMarker/utils/aruco_camera.json @@ -0,0 +1,98 @@ +{ + "name": "TestArUcoCamera", + "size": [1920, 1080], + "aruco_detector": { + "dictionary": { + "name": "DICT_ARUCO_ORIGINAL" + }, + "optic_parameters": { + "rms": 1.0, + "dimensions": [ + 1920, + 1080 + ], + "K": [ + [ + 1.0, + 0.0, + 1.0 + ], + [ + 0.0, + 1.0, + 1.0 + ], + [ + 0.0, + 0.0, + 1.0 + ] + ], + "D": [ + -1.0, + -0.5, + 0.0, + 0.5, + 1.0 + ] + }, + "parameters": { + "cornerRefinementMethod": 3, + "aprilTagQuadSigma": 2, + "aprilTagDeglitch": 1 + } + }, + "scenes": { + "TestSceneA" : { + "aruco_markers_group": { + "dictionary": "DICT_ARUCO_ORIGINAL", + "places": { + "0": { + "translation": [1, 0, 0], + "rotation": [0, 0, 0], + "size": 3.0 + }, + "1": { + "translation": [0, 1, 0], + "rotation": [0, 90, 0], + "size": 3.0 + } + } + }, + "layers": { + "Main" : { + "aoi_scene": "aoi_3d.obj" + } + }, + "angle_tolerance": 1.0, + "distance_tolerance": 2.0 + }, + "TestSceneB" : { + "aruco_markers_group": { + "dictionary": "DICT_ARUCO_ORIGINAL", + "places": { + "0": { + "translation": [1, 0, 0], + "rotation": [0, 0, 0], + "size": 3.0 + }, + "1": { + "translation": [0, 1, 0], + "rotation": [0, 90, 0], + "size": 3.0 + } + } + }, + "layers": { + "Main" : { + "aoi_scene": "aoi_3d.obj" + } + }, + "angle_tolerance": 1.0, + "distance_tolerance": 2.0 + } + }, + "layers": { + "Main": {} + } +} \ No newline at end of file diff --git a/src/argaze.test/ArUcoMarker/utils/detector.json b/src/argaze.test/ArUcoMarker/utils/detector.json new file mode 100644 index 0000000..8aada6d --- /dev/null +++ b/src/argaze.test/ArUcoMarker/utils/detector.json @@ -0,0 +1,42 @@ +{ + "dictionary": { + "name": "DICT_ARUCO_ORIGINAL" + }, + "marker_size": 3.0, + "optic_parameters": { + "rms": 1.0, + "dimensions": [ + 1920, + 1080 + ], + "K": [ + [ + 1.0, + 0.0, + 1.0 + ], + [ + 0.0, + 1.0, + 1.0 + ], + [ + 0.0, + 0.0, + 1.0 + ] + ], + "D": [ + -1.0, + -0.5, + 0.0, + 0.5, + 1.0 + ] + }, + "parameters": { + "cornerRefinementMethod": 3, + "aprilTagQuadSigma": 2, + "aprilTagDeglitch": 1 + } +} \ No newline at end of file diff --git a/src/argaze.test/ArUcoMarker/utils/detector_parameters.json b/src/argaze.test/ArUcoMarker/utils/detector_parameters.json new file mode 100644 index 0000000..d26a3fa --- /dev/null +++ b/src/argaze.test/ArUcoMarker/utils/detector_parameters.json @@ -0,0 +1,5 @@ +{ + "cornerRefinementMethod": 3, + "aprilTagQuadSigma": 2, + "aprilTagDeglitch": 1 +} \ No newline at end of file diff --git a/src/argaze.test/ArUcoMarker/utils/full_hd_board.png b/src/argaze.test/ArUcoMarker/utils/full_hd_board.png new file mode 100644 index 0000000..d30b300 Binary files /dev/null and b/src/argaze.test/ArUcoMarker/utils/full_hd_board.png differ diff --git a/src/argaze.test/ArUcoMarker/utils/full_hd_marker.png b/src/argaze.test/ArUcoMarker/utils/full_hd_marker.png new file mode 100644 index 0000000..42146fe Binary files /dev/null and b/src/argaze.test/ArUcoMarker/utils/full_hd_marker.png differ diff --git a/src/argaze.test/ArUcoMarker/utils/optic_parameters.json b/src/argaze.test/ArUcoMarker/utils/optic_parameters.json new file mode 100644 index 0000000..988731c --- /dev/null +++ b/src/argaze.test/ArUcoMarker/utils/optic_parameters.json @@ -0,0 +1,31 @@ +{ + "rms": 1.0, + "dimensions": [ + 1920, + 1080 + ], + "K": [ + [ + 1.0, + 0.0, + 1.0 + ], + [ + 0.0, + 1.0, + 1.0 + ], + [ + 0.0, + 0.0, + 1.0 + ] + ], + "D": [ + -1.0, + -0.5, + 0.0, + 0.5, + 1.0 + ] +} \ No newline at end of file diff --git a/src/argaze.test/ArUcoMarker/utils/scene.json b/src/argaze.test/ArUcoMarker/utils/scene.json new file mode 100644 index 0000000..bdd9ae8 --- /dev/null +++ b/src/argaze.test/ArUcoMarker/utils/scene.json @@ -0,0 +1,20 @@ +{ + "dictionary": { + "name": "DICT_ARUCO_ORIGINAL" + }, + "marker_size": 1, + "places": { + "0": { + "translation": [0, 0, 0], + "rotation": [0, 0, 0] + }, + "1": { + "translation": [10, 10, 0], + "rotation": [0, 0, 0] + }, + "2": { + "translation": [0, 10, 0], + "rotation": [0, 0, 0] + } + } +} diff --git a/src/argaze.test/ArUcoMarker/utils/scene.obj b/src/argaze.test/ArUcoMarker/utils/scene.obj new file mode 100644 index 0000000..1eb9f81 --- /dev/null +++ b/src/argaze.test/ArUcoMarker/utils/scene.obj @@ -0,0 +1,22 @@ +# .OBJ file for ArUcoMarkerGroup unitary test +o DICT_ARUCO_ORIGINAL#0_Marker +v -0.500000 -0.500000 0.000000 +v 0.500000 -0.500000 0.000000 +v -0.500000 0.500000 0.000000 +v 0.500000 0.500000 0.000000 +vn 0.0000 0.0000 1.0000 +f 1//1 2//1 4//1 3//1 +o DICT_ARUCO_ORIGINAL#1_Marker +v 9.500000 9.500000 0.000000 +v 10.500000 9.500000 0.000000 +v 9.500000 10.500000 0.000000 +v 10.500000 10.500000 0.000000 +vn 0.0000 0.0000 1.0000 +f 5//2 6//2 8//2 7//2 +o DICT_ARUCO_ORIGINAL#2_Marker +v -0.500000 9.500000 0.000000 +v 0.500000 9.500000 0.000000 +v -0.500000 10.500000 0.000000 +v 0.500000 10.500000 0.000000 +vn 0.0000 0.0000 1.0000 +f 9//3 10//3 12//3 11//3 diff --git a/src/argaze.test/ArUcoMarkers/ArUcoBoard.py b/src/argaze.test/ArUcoMarkers/ArUcoBoard.py deleted file mode 100644 index 0bfa568..0000000 --- a/src/argaze.test/ArUcoMarkers/ArUcoBoard.py +++ /dev/null @@ -1,50 +0,0 @@ -""" - -This program is free software: you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any later -version. -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -You should have received a copy of the GNU General Public License along with -this program. If not, see . -""" - -__author__ = "Théo de la Hogue" -__credits__ = [] -__copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)" -__license__ = "GPLv3" - -import unittest -import os - -from argaze.ArUcoMarkers import ArUcoBoard, ArUcoMarkersDictionary - -import numpy - -class TestArUcoBoardClass(unittest.TestCase): - """Test ArUcoBoard class.""" - - def test_new(self): - """Test ArUcoBoard creation using a dictionary instance.""" - - columns = 4 - rows = 3 - square_size = 2 - marker_size = 1 - - # Check ArUco board creation - aruco_dictionary = ArUcoMarkersDictionary.ArUcoMarkersDictionary('DICT_APRILTAG_16h5') - 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') - 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__': - - unittest.main() \ No newline at end of file diff --git a/src/argaze.test/ArUcoMarkers/ArUcoCamera.py b/src/argaze.test/ArUcoMarkers/ArUcoCamera.py deleted file mode 100644 index eb930ab..0000000 --- a/src/argaze.test/ArUcoMarkers/ArUcoCamera.py +++ /dev/null @@ -1,80 +0,0 @@ -""" - -This program is free software: you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any later -version. -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -You should have received a copy of the GNU General Public License along with -this program. If not, see . -""" - -__author__ = "Théo de la Hogue" -__credits__ = [] -__copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)" -__license__ = "GPLv3" - -import unittest -import os - -import argaze - -import numpy - -class TestArUcoCameraClass(unittest.TestCase): - """Test ArUcoCamera class.""" - - def test_from_json(self): - """Test ArUcoCamera creation from json file.""" - - # Edit test aruco camera file path - current_directory = os.path.dirname(os.path.abspath(__file__)) - json_filepath = os.path.join(current_directory, 'utils/aruco_camera.json') - - # Load test aruco camera - with argaze.load(json_filepath) as aruco_camera: - - # Check aruco camera meta data - self.assertEqual(aruco_camera.name, "TestArUcoCamera") - - # Check ArUco detector - self.assertEqual(aruco_camera.aruco_detector.dictionary.name, "DICT_ARUCO_ORIGINAL") - self.assertEqual(aruco_camera.aruco_detector.parameters.cornerRefinementMethod, 3) - self.assertEqual(aruco_camera.aruco_detector.parameters.aprilTagQuadSigma, 2) - self.assertEqual(aruco_camera.aruco_detector.parameters.aprilTagDeglitch, 1) - - # Check ArUco detector optic parameters - self.assertEqual(aruco_camera.aruco_detector.optic_parameters.rms, 1.0) - self.assertIsNone(numpy.testing.assert_array_equal(aruco_camera.aruco_detector.optic_parameters.dimensions, [1920, 1080])) - self.assertIsNone(numpy.testing.assert_array_equal(aruco_camera.aruco_detector.optic_parameters.K, [[1.0, 0.0, 1.0], [0.0, 1.0, 1.0], [0.0, 0.0, 1.0]])) - self.assertIsNone(numpy.testing.assert_array_equal(aruco_camera.aruco_detector.optic_parameters.D, [-1.0, -0.5, 0.0, 0.5, 1.0])) - - # Check camera scenes - self.assertEqual(len(aruco_camera.scenes), 2) - self.assertIsNone(numpy.testing.assert_array_equal(list(aruco_camera.scenes.keys()), ["TestSceneA", "TestSceneB"])) - - # Load test scene - ar_scene = aruco_camera.scenes["TestSceneA"] - - # Check Aruco scene - self.assertEqual(len(ar_scene.aruco_markers_group.places), 2) - self.assertIsNone(numpy.testing.assert_allclose(ar_scene.aruco_markers_group.places[0].corners[0], [-0.5, 1.5, 0.], rtol=0, atol=1e-3)) - self.assertEqual(ar_scene.aruco_markers_group.places[0].marker.identifier, 0) - - self.assertIsNone(numpy.testing.assert_allclose(ar_scene.aruco_markers_group.places[1].corners[0], [0., 2.5, -1.5], rtol=0, atol=1e-3)) - self.assertEqual(ar_scene.aruco_markers_group.places[1].marker.identifier, 1) - - # Check layers and AOI scene - self.assertEqual(len(ar_scene.layers.items()), 1) - self.assertEqual(len(ar_scene.layers["Main"].aoi_scene), 1) - self.assertEqual(ar_scene.layers["Main"].aoi_scene['Test'].points_number, 4) - - # Check ArScene - self.assertEqual(ar_scene.angle_tolerance, 1.0) - self.assertEqual(ar_scene.distance_tolerance, 2.0) - -if __name__ == '__main__': - - unittest.main() \ No newline at end of file diff --git a/src/argaze.test/ArUcoMarkers/ArUcoDetector.py b/src/argaze.test/ArUcoMarkers/ArUcoDetector.py deleted file mode 100644 index 62e8a09..0000000 --- a/src/argaze.test/ArUcoMarkers/ArUcoDetector.py +++ /dev/null @@ -1,149 +0,0 @@ -""" - -This program is free software: you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any later -version. -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -You should have received a copy of the GNU General Public License along with -this program. If not, see . -""" - -__author__ = "Théo de la Hogue" -__credits__ = [] -__copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)" -__license__ = "GPLv3" - -import unittest -import os -import math - -from argaze.ArUcoMarkers import ArUcoMarkersDictionary, ArUcoOpticCalibrator, ArUcoDetector, ArUcoBoard - -import cv2 as cv -import numpy - -class TestDetectorParametersClass(unittest.TestCase): - """Test DetectorParameters class.""" - - def test_from_json(self): - """Test DetectorParameters creation from json file.""" - - # Edit file path - current_directory = os.path.dirname(os.path.abspath(__file__)) - json_filepath = os.path.join(current_directory, 'utils/detector_parameters.json') - - # Load file - detector_parameters = ArUcoDetector.DetectorParameters.from_json(json_filepath) - - # Check data - self.assertEqual(detector_parameters.cornerRefinementMethod, 3) - self.assertEqual(detector_parameters.aprilTagQuadSigma, 2) - self.assertEqual(detector_parameters.aprilTagDeglitch, 1) - - # Check bad data access fails - with self.assertRaises(AttributeError): - - detector_parameters.unknown_data = 1 - -class TestArUcoDetectorClass(unittest.TestCase): - """Test ArUcoDetector class.""" - - def test_new(self): - """Test ArUcoDetector creation.""" - - aruco_detector = ArUcoDetector.ArUcoDetector(marker_size=3) - - # Check ArUcoDetector creation - self.assertEqual(aruco_detector.dictionary.name, 'DICT_ARUCO_ORIGINAL') - self.assertEqual(aruco_detector.marker_size, 3) - self.assertIsNone(numpy.testing.assert_array_equal(aruco_detector.optic_parameters.dimensions, [0, 0])) - self.assertEqual(aruco_detector.detected_markers_number(), 0) - self.assertEqual(aruco_detector.detected_markers(), {}) - - aruco_dictionary = ArUcoMarkersDictionary.ArUcoMarkersDictionary('DICT_APRILTAG_16h5') - aruco_detector = ArUcoDetector.ArUcoDetector(aruco_dictionary, 5.2) - - # Check ArUcoDetector creation - self.assertEqual(aruco_detector.dictionary.name, 'DICT_APRILTAG_16h5') - self.assertEqual(aruco_detector.marker_size, 5.2) - self.assertIsNone(numpy.testing.assert_array_equal(aruco_detector.optic_parameters.dimensions, [0, 0])) - self.assertEqual(aruco_detector.detected_markers_number(), 0) - self.assertEqual(aruco_detector.detected_markers(), {}) - - def test_from_json(self): - """Test ArUcoDetector creation.""" - - # Edit file path - current_directory = os.path.dirname(os.path.abspath(__file__)) - json_filepath = os.path.join(current_directory, 'utils/detector.json') - - # Load file - aruco_detector = ArUcoDetector.ArUcoDetector.from_json(json_filepath) - - # Check ArUcoDetector creation - self.assertEqual(aruco_detector.dictionary.name, 'DICT_ARUCO_ORIGINAL') - self.assertEqual(aruco_detector.marker_size, 3) - self.assertIsNone(numpy.testing.assert_array_equal(aruco_detector.optic_parameters.dimensions, [1920, 1080])) - self.assertEqual(aruco_detector.parameters.cornerRefinementMethod, 3) - self.assertEqual(aruco_detector.parameters.aprilTagQuadSigma, 2) - self.assertEqual(aruco_detector.parameters.aprilTagDeglitch, 1) - - def test_detect(self): - """Test detect method.""" - - aruco_detector = ArUcoDetector.ArUcoDetector(marker_size=3) - - # Load picture Full HD to test ArUcoMarker detection - current_directory = os.path.dirname(os.path.abspath(__file__)) - image = cv.imread(os.path.join(current_directory, 'utils/full_hd_marker.png')) - - # Check ArUcoMarker detection - aruco_detector.detect_markers(image) - - self.assertEqual(aruco_detector.detected_markers_number(), 1) - - self.assertEqual(aruco_detector.detected_markers()[0].dictionary, aruco_detector.dictionary) - self.assertEqual(aruco_detector.detected_markers()[0].identifier, 0) - self.assertEqual(aruco_detector.detected_markers()[0].size, 3) - - # Check corner positions with -/+ 10 pixels precision - self.assertIsNone(numpy.testing.assert_almost_equal(aruco_detector.detected_markers()[0].corners[0][0].astype(int), numpy.array([3823, 2073]), decimal=-1)) - self.assertIsNone(numpy.testing.assert_almost_equal(aruco_detector.detected_markers()[0].corners[0][1].astype(int), numpy.array([4177, 2073]), decimal=-1)) - self.assertIsNone(numpy.testing.assert_almost_equal(aruco_detector.detected_markers()[0].corners[0][2].astype(int), numpy.array([4177, 2427]), decimal=-1)) - self.assertIsNone(numpy.testing.assert_almost_equal(aruco_detector.detected_markers()[0].corners[0][3].astype(int), numpy.array([3823, 2427]), decimal=-1)) - - # Check marker pose estimation - aruco_detector.estimate_markers_pose([0]) - - # Check marker translation with -/+ 0.1 cm precision and rotation with -/+ 0.001 radian precision - self.assertIsNone(numpy.testing.assert_almost_equal(aruco_detector.detected_markers()[0].translation, numpy.array([33.87, 19.05, 0.]), decimal=1)) - self.assertIsNone(numpy.testing.assert_almost_equal(aruco_detector.detected_markers()[0].rotation, numpy.array([[1., 0., 0.], [0., -1., 0.], [0., 0., -1.]]), decimal=3)) - - # Check detect metrics - detect_count, markers_count = aruco_detector.detection_metrics - self.assertEqual(detect_count, 1) - self.assertEqual(markers_count[0], 1) - - def test_detect_board(self): - """Test detect board method.""" - - aruco_board = ArUcoBoard.ArUcoBoard(7, 5, 5, 3) - aruco_detector = ArUcoDetector.ArUcoDetector(marker_size=3) - - # Load picture Full HD to test ArUcoMarker board detection - current_directory = os.path.dirname(os.path.abspath(__file__)) - image = cv.imread(os.path.join(current_directory, 'utils/full_hd_board.png')) - - # Check ArUcoMarker board detection - aruco_detector.detect_board(image, aruco_board, aruco_board.markers_number) - - self.assertEqual(aruco_detector.board_corners_number(), aruco_board.corners_number) - self.assertEqual(len(aruco_detector.board_corners()), 24) - self.assertEqual(len(aruco_detector.board_corners_identifier()), 24) - -if __name__ == '__main__': - - unittest.main() \ No newline at end of file diff --git a/src/argaze.test/ArUcoMarkers/ArUcoMarker.py b/src/argaze.test/ArUcoMarkers/ArUcoMarker.py deleted file mode 100644 index de88623..0000000 --- a/src/argaze.test/ArUcoMarkers/ArUcoMarker.py +++ /dev/null @@ -1,40 +0,0 @@ -""" - -This program is free software: you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any later -version. -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -You should have received a copy of the GNU General Public License along with -this program. If not, see . -""" - -__author__ = "Théo de la Hogue" -__credits__ = [] -__copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)" -__license__ = "GPLv3" - -import unittest - -from argaze.ArUcoMarkers import ArUcoMarkersDictionary, ArUcoMarker - -class TestArUcoMarkerClass(unittest.TestCase): - """Test ArUcoMarker class.""" - - def test_new(self): - """Test ArUcoMarker creation.""" - - # Check DICT_ARUCO_ORIGINAL ArUcoMarker creation - aruco_dictionary = ArUcoMarkersDictionary.ArUcoMarkersDictionary('DICT_ARUCO_ORIGINAL') - - aruco_marker = aruco_dictionary.create_marker(0, 3) - - self.assertEqual(aruco_marker.dictionary, aruco_dictionary) - self.assertEqual(aruco_marker.identifier, 0) - self.assertEqual(aruco_marker.size, 3) - -if __name__ == '__main__': - - unittest.main() \ No newline at end of file diff --git a/src/argaze.test/ArUcoMarkers/ArUcoMarkersDictionary.py b/src/argaze.test/ArUcoMarkers/ArUcoMarkersDictionary.py deleted file mode 100644 index 7a5e9e8..0000000 --- a/src/argaze.test/ArUcoMarkers/ArUcoMarkersDictionary.py +++ /dev/null @@ -1,50 +0,0 @@ -""" - -This program is free software: you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any later -version. -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -You should have received a copy of the GNU General Public License along with -this program. If not, see . -""" - -__author__ = "Théo de la Hogue" -__credits__ = [] -__copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)" -__license__ = "GPLv3" - -import unittest - -from argaze.ArUcoMarkers import ArUcoMarkersDictionary - -class TestArUcoMarkersDictionaryClass(unittest.TestCase): - """Test ArUcoMarkersDictionary class.""" - - def test_new(self): - """Test ArUcoMarkersDictionary creation.""" - - # Check that ArUcoMarkersDictionary creation fails with bad name - with self.assertRaises(NameError): - - aruco_dictionary = ArUcoMarkersDictionary.ArUcoMarkersDictionary('BAD_DICT_NAME') - - # Check default ArUcoMarkersDictionary creation - aruco_dictionary = ArUcoMarkersDictionary.ArUcoMarkersDictionary() - - self.assertEqual(aruco_dictionary.name, 'DICT_ARUCO_ORIGINAL') - self.assertEqual(aruco_dictionary.format, '5X5') - self.assertEqual(aruco_dictionary.number, 1024) - - # Check DICT_APRILTAG_16h5 ArUcoMarkersDictionary creation - aruco_dictionary = ArUcoMarkersDictionary.ArUcoMarkersDictionary('DICT_APRILTAG_16h5') - - self.assertEqual(aruco_dictionary.name, 'DICT_APRILTAG_16h5') - self.assertEqual(aruco_dictionary.format, '4X4') - self.assertEqual(aruco_dictionary.number, 30) - -if __name__ == '__main__': - - unittest.main() \ No newline at end of file diff --git a/src/argaze.test/ArUcoMarkers/ArUcoOpticCalibrator.py b/src/argaze.test/ArUcoMarkers/ArUcoOpticCalibrator.py deleted file mode 100644 index 79d2ead..0000000 --- a/src/argaze.test/ArUcoMarkers/ArUcoOpticCalibrator.py +++ /dev/null @@ -1,61 +0,0 @@ -""" - -This program is free software: you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any later -version. -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -You should have received a copy of the GNU General Public License along with -this program. If not, see . -""" - -__author__ = "Théo de la Hogue" -__credits__ = [] -__copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)" -__license__ = "GPLv3" - -import unittest -import os - -from argaze.ArUcoMarkers import ArUcoOpticCalibrator - -import numpy - -class TestOpticParametersClass(unittest.TestCase): - """Test OpticParameters class.""" - - def test_new(self): - """Test OpticParameters creation.""" - - # Check defaut optic parameters creation - optic_parameters = ArUcoOpticCalibrator.OpticParameters() - - # Check ArUco optic parameters - self.assertEqual(optic_parameters.rms, 0.0) - - #self.assertEqual(type(optic_parameters.K), numpy.array) - - self.assertIsNone(numpy.testing.assert_array_equal(optic_parameters.dimensions, [0, 0])) - self.assertIsNone(numpy.testing.assert_array_equal(optic_parameters.K, ArUcoOpticCalibrator.K0)) - self.assertIsNone(numpy.testing.assert_array_equal(optic_parameters.D, ArUcoOpticCalibrator.D0)) - - def test_from_json(self): - - # Edit optic parameters file path - current_directory = os.path.dirname(os.path.abspath(__file__)) - json_filepath = os.path.join(current_directory, 'utils/optic_parameters.json') - - # Load optic parameters - optic_parameters = ArUcoOpticCalibrator.OpticParameters.from_json(json_filepath) - - # Check ArUco camera - self.assertEqual(optic_parameters.rms, 1.0) - self.assertIsNone(numpy.testing.assert_array_equal(optic_parameters.dimensions, [1920, 1080])) - self.assertIsNone(numpy.testing.assert_array_equal(optic_parameters.K, [[1.0, 0.0, 1.0], [0.0, 1.0, 1.0], [0.0, 0.0, 1.0]])) - self.assertIsNone(numpy.testing.assert_array_equal(optic_parameters.D, [-1.0, -0.5, 0.0, 0.5, 1.0])) - -if __name__ == '__main__': - - unittest.main() \ No newline at end of file diff --git a/src/argaze.test/ArUcoMarkers/ArUcoScene.py b/src/argaze.test/ArUcoMarkers/ArUcoScene.py deleted file mode 100644 index f29b1d3..0000000 --- a/src/argaze.test/ArUcoMarkers/ArUcoScene.py +++ /dev/null @@ -1,227 +0,0 @@ -""" - -This program is free software: you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any later -version. -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -You should have received a copy of the GNU General Public License along with -this program. If not, see . -""" - -__author__ = "Théo de la Hogue" -__credits__ = [] -__copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)" -__license__ = "GPLv3" - -import unittest -import os -import math - -from argaze.ArUcoMarkers import ArUcoMarkersGroup, ArUcoMarker - -import cv2 as cv -import numpy - -class TestArUcoMarkersGroupClass(unittest.TestCase): - - def new_from_obj(self): - - # Edit file path - current_directory = os.path.dirname(os.path.abspath(__file__)) - obj_filepath = os.path.join(current_directory, 'utils/scene.obj') - - # Load file - self.aruco_markers_group = ArUcoMarkersGroup.ArUcoMarkersGroup.from_obj(obj_filepath) - - def new_from_json(self): - - # Edit file path - current_directory = os.path.dirname(os.path.abspath(__file__)) - json_filepath = os.path.join(current_directory, 'utils/scene.json') - - # Load file - self.aruco_markers_group = ArUcoMarkersGroup.ArUcoMarkersGroup.from_json(json_filepath) - - def setup_markers(self): - - # Prepare detected markers - self.detected_markers = { - 0: ArUcoMarker.ArUcoMarker('DICT_ARUCO_ORIGINAL', 0, 1.), - 1: ArUcoMarker.ArUcoMarker('DICT_ARUCO_ORIGINAL', 1, 1.), - 2: ArUcoMarker.ArUcoMarker('DICT_ARUCO_ORIGINAL', 2, 1.), - 3: ArUcoMarker.ArUcoMarker('DICT_ARUCO_ORIGINAL', 3, 1.) - } - - # Prepare scene markers and remaining markers - self.scene_markers, self.remaining_markers = self.aruco_markers_group.filter_markers(self.detected_markers()) - - def test_new_from_obj(self): - """Test ArUcoMarkersGroup creation.""" - - self.new_from_obj() - self.setup_markers() - - # Check ArUcoMarkersGroup creation - self.assertEqual(len(self.aruco_markers_group.places), 3) - self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.identifiers, [0, 1, 2])) - self.assertEqual(self.aruco_markers_group.marker_size, 1.) - - self.assertEqual(self.aruco_markers_group.places[0].marker.identifier, 0) - self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[0].translation, [0., 0., 0.])) - self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[0].rotation, [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])) - - self.assertEqual(self.aruco_markers_group.places[1].marker.identifier, 1) - self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[1].translation, [10., 10., 0.])) - self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[1].rotation, [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])) - - self.assertEqual(self.aruco_markers_group.places[2].marker.identifier, 2) - self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[2].translation, [0., 10., 0.])) - self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[2].rotation, [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])) - - def test_new_from_json(self): - """Test ArUcoMarkersGroup creation.""" - - self.new_from_json() - self.setup_markers() - - # Check ArUcoMarkersGroup creation - self.assertEqual(len(self.aruco_markers_group.places), 3) - self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.identifiers, [0, 1, 2])) - self.assertEqual(self.aruco_markers_group.marker_size, 1.) - - self.assertEqual(self.aruco_markers_group.places[0].marker.identifier, 0) - self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[0].translation, [0., 0., 0.])) - self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[0].rotation, [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])) - - self.assertEqual(self.aruco_markers_group.places[1].marker.identifier, 1) - self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[1].translation, [10., 10., 0.])) - self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[1].rotation, [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])) - - self.assertEqual(self.aruco_markers_group.places[2].marker.identifier, 2) - self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[2].translation, [0., 10., 0.])) - self.assertIsNone(numpy.testing.assert_array_equal(self.aruco_markers_group.places[2].rotation, [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])) - - def test_filter_markers(self): - """Test ArUcoMarkersGroup markers filtering.""" - - self.new_from_obj() - self.setup_markers() - - # Check scene markers and remaining markers - self.assertEqual(len(self.scene_markers), 3) - self.assertEqual(len(self.remaining_markers), 1) - - self.assertIsNone(numpy.testing.assert_array_equal(list(self.scene_markers.keys()), self.aruco_markers_group.identifiers)) - self.assertIsNone(numpy.testing.assert_array_equal(list(self.remaining_markers.keys()), [3])) - - def test_check_markers_consistency(self): - """Test ArUcoMarkersGroup markers consistency checking.""" - - self.new_from_obj() - self.setup_markers() - - # Edit consistent marker poses - self.scene_markers[0].translation = numpy.array([1., 1., 5.]) - self.scene_markers[0].rotation = numpy.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) - - self.scene_markers[1].translation = numpy.array([11., 11., 5.]) - self.scene_markers[1].rotation = numpy.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) - - self.scene_markers[2].translation = numpy.array([1., 11., 5.]) - self.scene_markers[2].rotation = numpy.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) - - # Check consistency - consistent_markers, unconsistent_markers, unconsistencies = self.aruco_markers_group.check_markers_consistency(self.scene_markers, 1, 1) - - # Check consistent markers, unconsistent markers and unconsistencies - self.assertEqual(len(consistent_markers), 3) - self.assertEqual(len(unconsistent_markers), 0) - self.assertEqual(len(unconsistencies['rotation']), 0) - self.assertEqual(len(unconsistencies['translation']), 0) - - self.assertIsNone(numpy.testing.assert_array_equal(list(consistent_markers.keys()), self.aruco_markers_group.identifiers)) - - # Edit unconsistent marker poses - self.scene_markers[2].translation = numpy.array([5., 15., 5.]) - - # Check consistency - consistent_markers, unconsistent_markers, unconsistencies = self.aruco_markers_group.check_markers_consistency(self.scene_markers, 1, 1) - - # Check consistent markers, unconsistent markers and unconsistencies - self.assertEqual(len(consistent_markers), 2) - self.assertEqual(len(unconsistent_markers), 1) - self.assertEqual(len(unconsistencies['rotation']), 0) - self.assertEqual(len(unconsistencies['translation']), 2) - - self.assertIsNone(numpy.testing.assert_array_equal(list(unconsistent_markers.keys()), [2])) - self.assertIsNone(numpy.testing.assert_array_equal(list(unconsistencies['translation'].keys()), ['0/2', '1/2'])) - self.assertIsNone(numpy.testing.assert_array_equal(list(unconsistencies['translation']['0/2'].keys()), ['current', 'expected'])) - self.assertIsNone(numpy.testing.assert_array_equal(list(unconsistencies['translation']['1/2'].keys()), ['current', 'expected'])) - - def test_estimate_pose_from_single_marker(self): - """Test ArUcoMarkersGroup pose estimation from single marker.""" - - self.new_from_obj() - self.setup_markers() - - # Edit marke pose - self.scene_markers[0].translation = numpy.array([1., 1., 5.]) - self.scene_markers[0].rotation = numpy.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) - - # Estimate pose - tvec, rmat = self.aruco_markers_group.estimate_pose_from_single_marker(self.scene_markers[0]) - - self.assertIsNone(numpy.testing.assert_array_equal(tvec, [1., 1., 5.])) - self.assertIsNone(numpy.testing.assert_array_equal(rmat, [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])) - - def test_estimate_pose_from_markers(self): - """Test ArUcoMarkersGroup pose estimation from markers.""" - - self.new_from_obj() - self.setup_markers() - - # Edit markers pose - self.scene_markers[0].translation = numpy.array([1., 1., 5.]) - self.scene_markers[0].rotation = numpy.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) - - self.scene_markers[1].translation = numpy.array([11., 11., 5.]) - self.scene_markers[1].rotation = numpy.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) - - self.scene_markers[2].translation = numpy.array([1., 11., 5.]) - self.scene_markers[2].rotation = numpy.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) - - # Estimate pose - tvec, rmat = self.aruco_markers_group.estimate_pose_from_markers(self.scene_markers) - - self.assertIsNone(numpy.testing.assert_array_equal(tvec, [1., 1., 5.])) - self.assertIsNone(numpy.testing.assert_array_equal(rmat, [[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])) - - @unittest.skip("ArUcoMarkersGroup estimate_pose_from_axis_markers method is broken.") - def test_estimate_pose_from_axis_markers(self): - """Test ArUcoMarkersGroup pose estimation from axis markers.""" - - self.new_from_obj() - self.setup_markers() - - # Edit markers pose - self.scene_markers[0].translation = numpy.array([1., 1., 5.]) - self.scene_markers[0].rotation = numpy.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) - - self.scene_markers[1].translation = numpy.array([11., 11., 5.]) - self.scene_markers[1].rotation = numpy.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) - - self.scene_markers[2].translation = numpy.array([1., 11., 5.]) - self.scene_markers[2].rotation = numpy.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) - - # Estimate pose - tvec, rmat = self.aruco_markers_group.estimate_pose_from_axis_markers(self.scene_markers[2], self.scene_markers[1], self.scene_markers[0]) - - self.assertIsNone(numpy.testing.assert_array_equal(tvec, [1., 1., 5.])) - self.assertIsNone(numpy.testing.assert_array_equal(rmat, [[1., 0., 0.], [0., -1., 0.], [0., 0., -1.]])) - -if __name__ == '__main__': - - unittest.main() \ No newline at end of file diff --git a/src/argaze.test/ArUcoMarkers/__init__.py b/src/argaze.test/ArUcoMarkers/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/argaze.test/ArUcoMarkers/utils/aoi_3d.obj b/src/argaze.test/ArUcoMarkers/utils/aoi_3d.obj deleted file mode 100644 index 92e85bd..0000000 --- a/src/argaze.test/ArUcoMarkers/utils/aoi_3d.obj +++ /dev/null @@ -1,7 +0,0 @@ -o Test -v 0.000000 0.000000 0.000000 -v 25.000000 0.000000 0.000000 -v 0.000000 14.960000 0.000000 -v 25.000000 14.960000 0.000000 -s off -f 1 2 4 3 diff --git a/src/argaze.test/ArUcoMarkers/utils/aruco_camera.json b/src/argaze.test/ArUcoMarkers/utils/aruco_camera.json deleted file mode 100644 index 980dc9f..0000000 --- a/src/argaze.test/ArUcoMarkers/utils/aruco_camera.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "name": "TestArUcoCamera", - "size": [1920, 1080], - "aruco_detector": { - "dictionary": { - "name": "DICT_ARUCO_ORIGINAL" - }, - "optic_parameters": { - "rms": 1.0, - "dimensions": [ - 1920, - 1080 - ], - "K": [ - [ - 1.0, - 0.0, - 1.0 - ], - [ - 0.0, - 1.0, - 1.0 - ], - [ - 0.0, - 0.0, - 1.0 - ] - ], - "D": [ - -1.0, - -0.5, - 0.0, - 0.5, - 1.0 - ] - }, - "parameters": { - "cornerRefinementMethod": 3, - "aprilTagQuadSigma": 2, - "aprilTagDeglitch": 1 - } - }, - "scenes": { - "TestSceneA" : { - "aruco_markers_group": { - "dictionary": "DICT_ARUCO_ORIGINAL", - "places": { - "0": { - "translation": [1, 0, 0], - "rotation": [0, 0, 0], - "size": 3.0 - }, - "1": { - "translation": [0, 1, 0], - "rotation": [0, 90, 0], - "size": 3.0 - } - } - }, - "layers": { - "Main" : { - "aoi_scene": "aoi_3d.obj" - } - }, - "angle_tolerance": 1.0, - "distance_tolerance": 2.0 - }, - "TestSceneB" : { - "aruco_markers_group": { - "dictionary": "DICT_ARUCO_ORIGINAL", - "places": { - "0": { - "translation": [1, 0, 0], - "rotation": [0, 0, 0], - "size": 3.0 - }, - "1": { - "translation": [0, 1, 0], - "rotation": [0, 90, 0], - "size": 3.0 - } - } - }, - "layers": { - "Main" : { - "aoi_scene": "aoi_3d.obj" - } - }, - "angle_tolerance": 1.0, - "distance_tolerance": 2.0 - } - }, - "layers": { - "Main": {} - } -} \ No newline at end of file diff --git a/src/argaze.test/ArUcoMarkers/utils/detector.json b/src/argaze.test/ArUcoMarkers/utils/detector.json deleted file mode 100644 index 8aada6d..0000000 --- a/src/argaze.test/ArUcoMarkers/utils/detector.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "dictionary": { - "name": "DICT_ARUCO_ORIGINAL" - }, - "marker_size": 3.0, - "optic_parameters": { - "rms": 1.0, - "dimensions": [ - 1920, - 1080 - ], - "K": [ - [ - 1.0, - 0.0, - 1.0 - ], - [ - 0.0, - 1.0, - 1.0 - ], - [ - 0.0, - 0.0, - 1.0 - ] - ], - "D": [ - -1.0, - -0.5, - 0.0, - 0.5, - 1.0 - ] - }, - "parameters": { - "cornerRefinementMethod": 3, - "aprilTagQuadSigma": 2, - "aprilTagDeglitch": 1 - } -} \ No newline at end of file diff --git a/src/argaze.test/ArUcoMarkers/utils/detector_parameters.json b/src/argaze.test/ArUcoMarkers/utils/detector_parameters.json deleted file mode 100644 index d26a3fa..0000000 --- a/src/argaze.test/ArUcoMarkers/utils/detector_parameters.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "cornerRefinementMethod": 3, - "aprilTagQuadSigma": 2, - "aprilTagDeglitch": 1 -} \ No newline at end of file diff --git a/src/argaze.test/ArUcoMarkers/utils/full_hd_board.png b/src/argaze.test/ArUcoMarkers/utils/full_hd_board.png deleted file mode 100644 index d30b300..0000000 Binary files a/src/argaze.test/ArUcoMarkers/utils/full_hd_board.png and /dev/null differ diff --git a/src/argaze.test/ArUcoMarkers/utils/full_hd_marker.png b/src/argaze.test/ArUcoMarkers/utils/full_hd_marker.png deleted file mode 100644 index 42146fe..0000000 Binary files a/src/argaze.test/ArUcoMarkers/utils/full_hd_marker.png and /dev/null differ diff --git a/src/argaze.test/ArUcoMarkers/utils/optic_parameters.json b/src/argaze.test/ArUcoMarkers/utils/optic_parameters.json deleted file mode 100644 index 988731c..0000000 --- a/src/argaze.test/ArUcoMarkers/utils/optic_parameters.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "rms": 1.0, - "dimensions": [ - 1920, - 1080 - ], - "K": [ - [ - 1.0, - 0.0, - 1.0 - ], - [ - 0.0, - 1.0, - 1.0 - ], - [ - 0.0, - 0.0, - 1.0 - ] - ], - "D": [ - -1.0, - -0.5, - 0.0, - 0.5, - 1.0 - ] -} \ No newline at end of file diff --git a/src/argaze.test/ArUcoMarkers/utils/scene.json b/src/argaze.test/ArUcoMarkers/utils/scene.json deleted file mode 100644 index bdd9ae8..0000000 --- a/src/argaze.test/ArUcoMarkers/utils/scene.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "dictionary": { - "name": "DICT_ARUCO_ORIGINAL" - }, - "marker_size": 1, - "places": { - "0": { - "translation": [0, 0, 0], - "rotation": [0, 0, 0] - }, - "1": { - "translation": [10, 10, 0], - "rotation": [0, 0, 0] - }, - "2": { - "translation": [0, 10, 0], - "rotation": [0, 0, 0] - } - } -} diff --git a/src/argaze.test/ArUcoMarkers/utils/scene.obj b/src/argaze.test/ArUcoMarkers/utils/scene.obj deleted file mode 100644 index c233da2..0000000 --- a/src/argaze.test/ArUcoMarkers/utils/scene.obj +++ /dev/null @@ -1,22 +0,0 @@ -# .OBJ file for ArUcoMarkersGroup unitary test -o DICT_ARUCO_ORIGINAL#0_Marker -v -0.500000 -0.500000 0.000000 -v 0.500000 -0.500000 0.000000 -v -0.500000 0.500000 0.000000 -v 0.500000 0.500000 0.000000 -vn 0.0000 0.0000 1.0000 -f 1//1 2//1 4//1 3//1 -o DICT_ARUCO_ORIGINAL#1_Marker -v 9.500000 9.500000 0.000000 -v 10.500000 9.500000 0.000000 -v 9.500000 10.500000 0.000000 -v 10.500000 10.500000 0.000000 -vn 0.0000 0.0000 1.0000 -f 5//2 6//2 8//2 7//2 -o DICT_ARUCO_ORIGINAL#2_Marker -v -0.500000 9.500000 0.000000 -v 0.500000 9.500000 0.000000 -v -0.500000 10.500000 0.000000 -v 0.500000 10.500000 0.000000 -vn 0.0000 0.0000 1.0000 -f 9//3 10//3 12//3 11//3 -- cgit v1.1