aboutsummaryrefslogtreecommitdiff
path: root/src/argaze/ArUcoMarkers/ArUcoCamera.py
blob: 92cde9f1f4e2fb89510e68db4de642d813e09f18 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/usr/bin/env python

import json
import numpy
import cv2.aruco as aruco

class ArUcoCamera():
    """Handle optical parameters with:
        - camera matrix as K,
        - camera distorsion coefficients as D."""

    def __init__(self):
        """Define optical parameters."""

        self.__rms = 0              # root mean square error

        self.__dimensions = [0, 0]  # dimensions of frame where to apply optical parameters (in pixel)

        self.__K = []               # intrinsic parameters matrix (focal lengths and principal point)
        self.__D = []               # distortion coefficients vector

        # define calibration data
        self.__corners_set_number = 0
        self.__corners_set = []
        self.__corners_set_ids = []

    def __del__(self):
        pass

    def load_calibration_file(self, camera_calibration_filepath):
        """Load optical parameters from .json file."""

        with open(camera_calibration_filepath) as calibration_file:

            calibration_data = json.load(calibration_file)

            self.__rms = calibration_data['rms']
            self.__dimensions = calibration_data['dimensions']
            self.__K = numpy.array(calibration_data['camera matrix'])
            self.__D = numpy.array(calibration_data['distortion coefficients'])

    def save_calibration_file(self, camera_calibration_filepath):
        """Save optical parameters into .json file."""

        calibration_data = {'rms': self.__rms, 'dimensions': self.__dimensions, 'camera matrix': self.__K.tolist(), 'distortion coefficients': self.__D.tolist()}

        with open(camera_calibration_filepath, 'w', encoding='utf-8') as calibration_file:

            json.dump(calibration_data, calibration_file, ensure_ascii=False, indent=4)

    @property
    def rms(self) -> float:
        """Get Root Mean Square (rms) error."""

        return self.__rms

    @property
    def K(self) -> numpy.array:
        """Get camera intrinsic parameters matrix."""

        return self.__K

    @property
    def D(self) -> numpy.array:
        """Get camera distorsion coefficients vector."""

        return self.__D

    def calibrate(self, board, frame_width, frame_height):
        """Retrieve camera K and D from stored calibration data."""

        if self.__corners_set_number > 0:

            self.__dimensions = [frame_width, frame_height]
            self.__rms, self.__K, self.__D, r, t = aruco.calibrateCameraCharuco(self.__corners_set, self.__corners_set_ids, board.model, self.__dimensions, None, None)

    def reset_calibration_data(self):
        """Clear all calibration data."""

        self.__corners_set_number = 0
        self.__corners_set = []
        self.__corners_set_ids = []

    def store_calibration_data(self, corners, corners_identifiers):
        """Store calibration data."""

        self.__corners_set_number += 1
        self.__corners_set.append(corners)
        self.__corners_set_ids.append(corners_identifiers)

    @property
    def calibration_data_count(self) -> int:
        """Get how much calibration data are stored."""

        return self.__corners_set_number