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 = [] # camera matrix (focal lengths and principal point)
self.__D = [] # distortion coefficients
# 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 matrix."""
return self.__K
@property
def D(self) -> numpy.array:
"""Get camera distorsion coefficients."""
return self.__D
def calibrate(self, board, frame_width, frame_height):
"""Retrieve camera optical parameters 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
|