aboutsummaryrefslogtreecommitdiff
path: root/docs/user_guide/aruco_markers/camera_calibration.md
blob: ea2c51a7434c681f07f42301d898c15fb08218e5 (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
Camera calibration
==================

Any camera device have to be calibrated to compensate its optical distorsion.

![Camera calibration](../../img/camera_calibration.png)

The first step to calibrate a camera is to create an [ArUcoBoard](/argaze/#argaze.ArUcoMarkers.ArUcoBoard) like in the code below:

``` python
from argaze.ArUcoMarkers import ArUcoMarkersDictionary, ArUcoBoard

# Create ArUco dictionary
aruco_dictionary = ArUcoMarkersDictionary.ArUcoMarkersDictionary('DICT_APRILTAG_16h5')

# Create an ArUco board of 7 columns and 5 rows with 5 cm squares with 3cm ArUco markers inside
aruco_board = ArUcoBoard.ArUcoBoard(7, 5, 5, 3, aruco_dictionary)

# Export ArUco board with 300 dpi resolution
aruco_board.save('./calibration_board.png', 300)
```

Then, the calibration process needs to make many different captures of an [ArUcoBoard](/argaze/#argaze.ArUcoMarkers.ArUcoBoard) through the camera and then, pass them to an [ArUcoDetector](/argaze/#argaze.ArUcoMarkers.ArUcoDetector.ArUcoDetector) instance to detect board corners and store them as calibration data to an [ArUcoOpticCalibrator](/argaze/#argaze.ArUcoMarkers.ArUcoOpticCalibrator) for final calibration process.

![Calibration step](../../img/camera_calibration_step.png)

The sample of code below shows how to detect board corners into camera frames, store detected corners then process them to build calibration data and, finally, save it into a JSON file:

``` python
from argaze.ArUcoMarkers import ArUcoMarkersDictionary, ArUcoOpticCalibrator, ArUcoBoard, ArUcoDetector

# Create ArUco dictionary
aruco_dictionary = ArUcoMarkersDictionary.ArUcoMarkersDictionary('DICT_APRILTAG_16h5')

# Create ArUco optic calibrator
aruco_optic_calibrator = ArUcoOpticCalibrator.ArUcoOpticCalibrator()

# Create ArUco board of 7 columns and 5 rows with 5 cm squares with 3cm aruco markers inside
# Note: This board is the one expected during further board tracking
expected_aruco_board = ArUcoBoard.ArUcoBoard(7, 5, 5, 3, aruco_dictionary)

# Create ArUco detector
aruco_detector = ArUcoDetector.ArUcoDetector(dictionary=aruco_dictionary, marker_size=3)

# Capture frames from a live Full HD video stream (1920x1080)
while video_stream.is_alive():

    frame = video_stream.read()

    # Detect all board corners in frame
    aruco_detector.detect_board(frame, expected_aruco_board, expected_aruco_board.markers_number)

    # If board corners are detected
    if aruco_detector.board_corners_number > 0:

        # Draw board corners to show that board tracking succeeded
        aruco_detector.draw_board(frame)

        # Append tracked board data for further calibration processing 
        aruco_optic_calibrator.store_calibration_data(aruco_detector.board_corners, aruco_detector.board_corners_identifier)

# Start camera calibration processing for Full HD image resolution
print('Calibrating camera...')
optic_parameters = aruco_optic_calibrator.calibrate(aruco_board, dimensions=(1920, 1080))

if optic_parameters:

    print('\nCalibration succeeded!')

    print(f'\nRMS:\n{optic_parameters.rms}')
    print(f'\nDimensions:\n{optic_parameters.dimensions[0]}x{optic_parameters.dimensions[1]}')
    print(f'\nCamera matrix:\n{optic_parameters.K}')
    print(f'\nDistortion coefficients:\n{optic_parameters.D}')

    optic_parameters.to_json(f'{args.output}/calibration.json')

    print(f'\ncalibration.json file exported into {args.output} folder')

else:

    print('\nCalibration error.')
```

Then, the camera calibration data are loaded to compensate optical distorsion during [ArUcoMarkers](/argaze/#argaze.ArUcoMarkers.ArUcoMarker) detection:

``` python
from argaze.ArUcoMarkers import ArUcoOpticCalibrator

# Load camera optic parameters
optic_parameters = ArUcoOpticCalibrator.OpticParameters.from_json('./calibration.json')
```