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') ```