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
|
#!/usr/bin/env python
import argparse
import os
import time
from argaze.TobiiGlassesPro2 import TobiiController, TobiiVideo
from argaze.ArUcoMarkers import ArUcoBoard, ArUcoTracker, ArUcoCamera
import cv2 as cv
def main():
"""
Captures board pictures and finally outputs camera calibration data into a .json file.
- Export and print a calibration board using
- Place the calibration board in order to view it entirely on screen and move the camera in many configurations (orientation and distance) : the script will automatically take pictures. Do this step with a good lighting and a clear background.
- Once enough pictures have been captured (~20), press Esc key then, wait for the camera calibration processing.
- Finally, check rms parameter: it should be between 0. and 1. if the calibration suceeded (lower is better).
### Reference:
- [Camera calibration using ArUco marker tutorial](https://automaticaddison.com/how-to-perform-camera-calibration-using-opencv/)
"""
# manage arguments
parser = argparse.ArgumentParser(description=main.__doc__.split('-')[0])
parser.add_argument('columns', metavar='COLS_NUMBER', type=int, default=7, help='number of columns')
parser.add_argument('rows', metavar='ROWS_NUMBER', type=int, default=5, help='number of rows')
parser.add_argument('square_size', metavar='SQUARE_SIZE', type=float, default=5, help='square size (cm)')
parser.add_argument('marker_size', metavar='MARKER_SIZE', type=float, default=3, help='marker size (cm)')
parser.add_argument('-t', '--tobii_ip', metavar='TOBII_IP', type=str, default='192.168.1.10', help='tobii glasses ip')
parser.add_argument('-o', '--output', metavar='OUT', type=str, default='camera.json', help='destination filepath')
parser.add_argument('-d', '--dictionary', metavar='DICT', type=str, default='DICT_ARUCO_ORIGINAL', help='aruco marker dictionnary (DICT_4X4_50, DICT_4X4_100, DICT_4X4_250, DICT_4X4_1000, DICT_5X5_50, DICT_5X5_100, DICT_5X5_250, DICT_5X5_1000, DICT_6X6_50, DICT_6X6_100, DICT_6X6_250, DICT_6X6_1000, DICT_7X7_50, DICT_7X7_100, DICT_7X7_250, DICT_7X7_1000, DICT_ARUCO_ORIGINAL,DICT_APRILTAG_16h5, DICT_APRILTAG_25h9, DICT_APRILTAG_36h10, DICT_APRILTAG_36h11)')
args = parser.parse_args()
# Create tobii controller
tobii_controller = TobiiController.TobiiController(args.tobii_ip, 'myProject', 'mySelf')
tobii_controller.set_video_freq_25()
# Enable tobii video stream
tobii_video_stream = tobii_controller.enable_video_stream()
# Create aruco camera
aruco_camera = ArUcoCamera.ArUcoCamera()
# Create aruco board
aruco_board = ArUcoBoard.ArUcoBoard(args.dictionary, args.columns, args.rows, args.square_size, args.marker_size)
# Create aruco tracker
aruco_tracker = ArUcoTracker.ArUcoTracker(args.dictionary, args.marker_size, aruco_camera)
# Start tobii glasses streaming
tobii_controller.start_streaming()
print("Camera calibration starts")
print("Waiting for calibration board...")
expected_markers_number = aruco_board.get_markers_number()
expected_corners_number = aruco_board.get_corners_number()
# capture loop
try:
while tobii_video_stream.is_alive():
# capture frame with a full displayed board
video_ts, video_frame = tobii_video_stream.read()
# track all markers in the board
aruco_tracker.track_board(video_frame.matrix, aruco_board, expected_markers_number)
# draw only markers
aruco_tracker.draw(video_frame.matrix)
# draw current calibration data count
cv.putText(video_frame.matrix, f'Capture: {aruco_camera.get_calibration_data_count()}', (50, 50), cv.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv.LINE_AA)
cv.imshow('Tobii Camera Calibration', video_frame.matrix)
# if all board corners are detected
if aruco_tracker.get_board_corners_number() == expected_corners_number:
# draw board corners to notify a capture is done
aruco_tracker.draw_board(video_frame.matrix)
# append data
aruco_camera.store_calibration_data(aruco_tracker.get_board_corners(), aruco_tracker.get_board_corners_ids())
cv.imshow('Tobii Camera Calibration', video_frame.matrix)
# close window using 'Esc' key
if cv.waitKey(1) == 27:
break
# exit on 'ctrl+C' interruption
except KeyboardInterrupt:
pass
# stop frame display
cv.destroyAllWindows()
# Stop tobii glasses streaming
tobii_controller.stop_streaming()
print('\nCalibrating camera...')
aruco_camera.calibrate(aruco_board, video_frame.width, video_frame.height)
print('\nCalibration succeeded!')
print(f'\nRMS:\n{aruco_camera.get_rms()}')
print(f'\nDimensions:\n{video_frame.width}x{video_frame.height}')
print(f'\nCamera matrix:\n{aruco_camera.get_K()}')
print(f'\nDistortion coefficients:\n{aruco_camera.get_D()}')
aruco_camera.save_calibration_file(args.output)
print(f'\nCalibration data exported into {args.output} file')
if __name__ == '__main__':
main()
|