-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathwebcam_calibration_process_images.py
175 lines (141 loc) · 5.84 KB
/
webcam_calibration_process_images.py
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
import cv2
import time
import glob
import time
import cv2.aruco as aruco
import webcam_calibration_aruco_board as ab
import numpy as np
from datetime import datetime
import yaml
import webcam as wc
import pprint as pp
from image_processing_helpers import fit_image_to_screen
aruco_dict = ab.aruco_dict
aruco_board = ab.board
camera_name = 'Logitech Webcam C930e'
image_width = 1920
image_height = 1080
fps = 30
num_images_to_collect = 60
time_between_images_sec = 0.5
image_directory = wc.get_calibration_directory(camera_name, image_width, image_height)
image_base_name = 'webcam_calibration_image'
file_name_pattern = image_directory + image_base_name + '_*.png'
file_names = glob.glob(file_name_pattern)
print('found ' + str(len(file_names)) + ' calibration images')
all_object_points = []
all_image_points = []
image_size = None
number_of_images = 0
number_of_points = 0
images_used_for_calibration = []
detector_parameters = aruco.DetectorParameters()
refine_parameters = aruco.RefineParameters()
aruco_detector = aruco.ArucoDetector(aruco_dict, detector_parameters, refine_parameters)
charuco_parameters = aruco.CharucoParameters()
charuco_detector = aruco.CharucoDetector(aruco_board, charuco_parameters, detector_parameters, refine_parameters)
for f in file_names:
color_image = cv2.imread(f)
number_of_images = number_of_images + 1
if image_size is None:
image_size = color_image.shape
print('image_size =', image_size)
elif image_size != color_image.shape:
print('ERROR: previous image_size', image_size, ' is not equal to the current image size', color_image.shape)
exit()
charuco_corners, charuco_ids, marker_corners, marker_ids = charuco_detector.detectBoard(color_image)
print('filename =', f)
if False:
print()
print('********************************')
print(' DETECT MARKERS OUTPUT ')
print()
print('marker_corners =', marker_corners)
print('_____')
print('marker_ids =', marker_ids)
print('_____')
print('rejected =', rejected)
print('********************************')
print()
if (marker_ids is None) or (charuco_ids is None):
print('marker_ids =', marker_ids)
print('charuco_ids =', charuco_ids)
else:
if False:
print()
print('********************************')
print(' CHARUCO CORNERS OUTPUT ')
print()
print('charuco_corners =', charuco_corners)
print('_____')
print('charuco_ids =', charuco_ids)
print('_____')
print('rejected =', rejected)
print('********************************')
print()
print('len(charuco_ids) =', len(charuco_ids))
if len(charuco_ids) > 0:
object_points, image_points = aruco_board.matchImagePoints(charuco_corners, charuco_ids)
if True:
print()
print('len(object_points) =', len(object_points))
print('len(image_points) =', len(image_points))
# A view with fewer than eight points results in
# cv2.calibrateCamera throwing an error like the following:
# projection_error, camera_matrix, distortion_coefficients, rotation_vectors, translation_vectors = cv2.calibrateCamera( cv2.error: OpenCV(4.8.1) /io/opencv/modules/calib3d/src/calibration.cpp:1213: error: (-215:Assertion failed) fabs(sc) > DBL_EPSILON in function 'cvFindExtrinsicCameraParams2'
if (len(object_points) >= 8):
number_of_points = number_of_points + len(object_points)
all_object_points.append(object_points)
all_image_points.append(image_points)
images_used_for_calibration.append(f)
if False:
print()
print('********************************')
print(' MATCH IMAGE POINTS OUTPUT ')
print()
print('object_points =', object_points)
print('_____')
print('image_points =', image_points)
print()
print('********************************')
print()
aruco.drawDetectedCornersCharuco(color_image, charuco_corners, charuco_ids)
cv2.imshow('Detected Charuco Corners', fit_image_to_screen(color_image))
cv2.waitKey(1)
# Perform Calibration
size = (image_size[1], image_size[0])
print()
print('POINTS USED FOR CALIBRATION')
print('number of images with suitable points =', len(images_used_for_calibration))
print('len(all_object_points) =', len(all_object_points))
print('len(all_image_points) =', len(all_image_points))
projection_error, camera_matrix, distortion_coefficients, rotation_vectors, translation_vectors = cv2.calibrateCamera(
all_object_points,
all_image_points,
size,
None,
None
)
calibration_results = {
'camera_name' : camera_name,
'calibration_date' : datetime.now(),
'image_size' : list(image_size),
'number_of_images_processed' : number_of_images,
'number_of_images_used' : len(images_used_for_calibration),
'number_of_corresponding_points_used' : number_of_points,
'projection_error' : projection_error,
'camera_matrix' : camera_matrix,
'distortion_coefficients' : distortion_coefficients
}
print()
print('calibration_results =')
pp.pprint(calibration_results)
print()
# Convert from Numpy arrays to human-readable lists
calibration_results = { (k) : (v.tolist() if 'tolist' in dir(v) else v) for k, v in calibration_results.items()}
results_file_time = time.strftime("%Y%m%d%H%M%S")
results_file_name = image_directory + 'camera_calibration_results_' + results_file_time + '.yaml'
with open(results_file_name, 'w') as file:
yaml.dump(calibration_results, file, sort_keys=True)
print('saved calibration results to', results_file_name)
print()