100 fx = camera_matrix[0,0]
101 fy = camera_matrix[1,1]
102 focal = 2 / (fx + fy)
103 f_scale = scale_focal * focal
106 X_img_plane = np.ones((4,5))
107 X_img_plane[0:3,0] = [-width, height, f_scale]
108 X_img_plane[0:3,1] = [width, height, f_scale]
109 X_img_plane[0:3,2] = [width, -height, f_scale]
110 X_img_plane[0:3,3] = [-width, -height, f_scale]
111 X_img_plane[0:3,4] = [-width, height, f_scale]
114 X_triangle = np.ones((4,3))
115 X_triangle[0:3,0] = [-width, -height, f_scale]
116 X_triangle[0:3,1] = [0, -2*height, f_scale]
117 X_triangle[0:3,2] = [width, -height, f_scale]
120 X_center1 = np.ones((4,2))
121 X_center1[0:3,0] = [0, 0, 0]
122 X_center1[0:3,1] = [-width, height, f_scale]
124 X_center2 = np.ones((4,2))
125 X_center2[0:3,0] = [0, 0, 0]
126 X_center2[0:3,1] = [width, height, f_scale]
128 X_center3 = np.ones((4,2))
129 X_center3[0:3,0] = [0, 0, 0]
130 X_center3[0:3,1] = [width, -height, f_scale]
132 X_center4 = np.ones((4,2))
133 X_center4[0:3,0] = [0, 0, 0]
134 X_center4[0:3,1] = [-width, -height, f_scale]
137 X_frame1 = np.ones((4,2))
138 X_frame1[0:3,0] = [0, 0, 0]
139 X_frame1[0:3,1] = [f_scale/2, 0, 0]
141 X_frame2 = np.ones((4,2))
142 X_frame2[0:3,0] = [0, 0, 0]
143 X_frame2[0:3,1] = [0, f_scale/2, 0]
145 X_frame3 = np.ones((4,2))
146 X_frame3[0:3,0] = [0, 0, 0]
147 X_frame3[0:3,1] = [0, 0, f_scale/2]
150 return [X_img_plane, X_triangle, X_center1, X_center2, X_center3, X_center4, X_frame1, X_frame2, X_frame3]
152 return [X_img_plane, X_triangle, X_center1, X_center2, X_center3, X_center4]
155 width = board_width*square_size
156 height = board_height*square_size
159 X_board = np.ones((4,5))
160 X_board[0:3,0] = [0,0,0]
161 X_board[0:3,1] = [width,0,0]
162 X_board[0:3,2] = [width,height,0]
163 X_board[0:3,3] = [0,height,0]
164 X_board[0:3,4] = [0,0,0]
167 X_frame1 = np.ones((4,2))
168 X_frame1[0:3,0] = [0, 0, 0]
169 X_frame1[0:3,1] = [height/2, 0, 0]
171 X_frame2 = np.ones((4,2))
172 X_frame2[0:3,0] = [0, 0, 0]
173 X_frame2[0:3,1] = [0, height/2, 0]
175 X_frame3 = np.ones((4,2))
176 X_frame3[0:3,0] = [0, 0, 0]
177 X_frame3[0:3,1] = [0, 0, height/2]
180 return [X_board, X_frame1, X_frame2, X_frame3]
185 extrinsics, board_width, board_height, square_size,
187 from matplotlib
import cm
189 min_values = np.zeros((3,1))
191 max_values = np.zeros((3,1))
196 X_static =
create_board_model(extrinsics, board_width, board_height, square_size,
True)
199 X_moving =
create_board_model(extrinsics, board_width, board_height, square_size,
True)
201 cm_subsection = linspace(0.0, 1.0, extrinsics.shape[0])
202 colors = [ cm.jet(x)
for x
in cm_subsection ]
204 for i
in range(len(X_static)):
205 X = np.zeros(X_static[i].shape)
206 for j
in range(X_static[i].shape[1]):
208 ax.plot3D(X[0,:], X[1,:], X[2,:], color=
'r')
209 min_values = np.minimum(min_values, X[0:3,:].min(1))
210 max_values = np.maximum(max_values, X[0:3,:].max(1))
212 for idx
in range(extrinsics.shape[0]):
214 R = Rotation.from_rotvec(extrinsics[idx,0:3]).as_matrix()
217 cMo[0:3,3] = extrinsics[idx,3:6]
218 for i
in range(len(X_moving)):
219 X = np.zeros(X_moving[i].shape)
220 for j
in range(X_moving[i].shape[1]):
222 ax.plot3D(X[0,:], X[1,:], X[2,:], color=colors[idx])
223 min_values = np.minimum(min_values, X[0:3,:].min(1))
224 max_values = np.maximum(max_values, X[0:3,:].max(1))
226 return min_values, max_values
231 parser = argparse.ArgumentParser(description=
'Plot camera calibration extrinsics.',
232 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
233 parser.add_argument(
'--calibration', type=str, default=
'camera.xml',
234 help=
'XML camera calibration file.')
235 parser.add_argument(
'--cam_width', type=float, default=0.064/2,
236 help=
'Width/2 of the displayed camera.')
237 parser.add_argument(
'--cam_height', type=float, default=0.048/2,
238 help=
'Height/2 of the displayed camera.')
239 parser.add_argument(
'--scale_focal', type=float, default=40,
240 help=
'Value to scale the focal length.')
241 parser.add_argument(
'--cameraCentric', action=
'store_true',
242 help=
'If argument is present, the camera is static and the calibration boards are moving.')
243 args = parser.parse_args()
245 tree = ET.parse(args.calibration)
246 root = tree.getroot()
248 def loadCameraInfo(root):
250 for camera
in root.iter(
'camera'):
251 pattern_type = PatternType.CHESSBOARD
252 if camera.find(
'additional_information').find(
'calibration_pattern_type').text ==
'Circles grid':
253 pattern_type = PatternType.CIRCLES_GRID
255 board_size = re.search(
r"(\d+)x(\d+)", camera.find(
'additional_information').find(
'board_size').text)
258 for cMo
in camera.find(
'additional_information').find(
'camera_poses').iter(
'cMo'):
262 camera.find(
'name').text, int(camera.find(
'image_width').text), int(camera.find(
'image_height').text), \
263 float(camera.find(
'model').find(
'px').text), float(camera.find(
'model').find(
'py').text), \
264 float(camera.find(
'model').find(
'u0').text), float(camera.find(
'model').find(
'v0').text), \
265 pattern_type, int(board_size.group(1)), int(board_size.group(2)), \
266 float(camera.find(
'additional_information').find(
'square_size').text), \
270 return camera_info_vec
272 camera_info_vec = loadCameraInfo(root)
274 for camera_info
in camera_info_vec:
275 print(
'\n', camera_info)
277 import matplotlib.pyplot
as plt
278 from mpl_toolkits.mplot3d
import Axes3D
282 ax = fig.add_subplot(projection=
'3d')
285 cMo_vec = camera_info.cMo_vec
286 extrinsics = np.empty((len(cMo_vec), 6), np.float64)
287 for idx, cMo
in enumerate(cMo_vec):
288 extrinsics[idx, :3] = cMo.pose[3:]
289 extrinsics[idx, 3:] = cMo.pose[:3]
291 cam_width = args.cam_width
292 cam_height = args.cam_height
293 scale_focal = args.scale_focal
294 pattern_centric =
not args.cameraCentric
295 min_values, max_values =
draw_camera_boards(ax, camera_info.intrinsics, cam_width, cam_height,
296 scale_focal, extrinsics, camera_info.board_width,
297 camera_info.board_height, camera_info.square_size,
300 X_min = min_values[0]
301 X_max = max_values[0]
302 Y_min = min_values[1]
303 Y_max = max_values[1]
304 Z_min = min_values[2]
305 Z_max = max_values[2]
306 max_range = np.array([X_max-X_min, Y_max-Y_min, Z_max-Z_min]).max() / 2.0
308 mid_x = (X_max+X_min) * 0.5
309 mid_y = (Y_max+Y_min) * 0.5
310 mid_z = (Z_max+Z_min) * 0.5
311 ax.set_xlim(mid_x - max_range, mid_x + max_range)
312 ax.set_ylim(mid_y - max_range, mid_y + max_range)
313 ax.set_zlim(mid_z - max_range, mid_z + max_range)
319 ax.set_title(
'Camera Poses Visualization')
324 ax.set_title(
'Calibration Board Poses Visualization')