Repository: opencv
Issue: Using Charuco Board to get camera intrinsics in opencv-python
Labels: question (invalid tracker)

### Describe the doc issue

Hi, I am having issues finding updated documentation on the process for getting calibration matrix and dist values in opencv using python. I am a bit new to this process as a whole and was hoping for some guidance and help. 
Here I have attached the script I have been trying to build, this is what I have come up with so far with opencv 4.10, however there are still some function calls that don't seem to exist in Aruco anymore. Any help would be appreciated or potentially a sample script would be great!
`import cv2
import os
import numpy as np
import logging
import matplotlib.pyplot as plt
import matplotlib as mpl
from cv2 import aruco
#set logging level to info or above
logging.basicConfig(level=logging.INFO)
#set output path
output = r"C:\Users\patrnih1\Documents\Python_Scripts\Intrinsics\output.txt"

# ------------------------------
# ENTER YOUR REQUIREMENTS HERE:
class ArucoError(Exception):
    pass


def create_aruco(columns, rows, square_length, marker_length, dictionary):
    if dictionary == 6:
        aruco_dict = cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_6X6_250)
        board = cv2.aruco.CharucoBoard((columns, rows), square_length, marker_length, aruco_dict)
    elif dictionary == 4:
        aruco_dict = cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_4X4_50)
        board = cv2.aruco.CharucoBoard((columns, rows), square_length, marker_length, aruco_dict)
    elif dictionary == 5:
        aruco_dict = cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_5X5_250)
        board = cv2.aruco.CharucoBoard((columns, rows), square_length, marker_length, aruco_dict)
    elif dictionary == 7:
        aruco_dict = cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_7X7_250)
        board = cv2.aruco.CharucoBoard((columns, rows), square_length, marker_length, aruco_dict)
    else:
        raise ArucoError("Invalid dictionary")
    pass
    imboard = board.generateImage((2000, 200))
    cv2.imwrite(r"C:\Users\patrnih1\Documents\Python_Scripts\Intrinsics\charuco.png", imboard)
    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)
    plt.imshow(imboard, cmap=mpl.colormaps['Greys'], interpolation="nearest")
    ax.axis("off")
    plt.show()
    return aruco_dict, board
# ...
PATH_TO_YOUR_IMAGES = '/Users/Ed/Downloads/Calibration_Images'
# ------------------------------

def calibrate_and_save_parameters(ARUCO_DICT, board):
    # Define the aruco dictionary and charuco board
    SQUARES_VERTICALLY = board.size[0]
    SQUARES_HORIZONTALLY = board.size[1]
    SQUARE_LENGTH = board.squareLength
    MARKER_LENGTH = board.markerLength
    dictionary = cv2.aruco.getPredefinedDictionary(ARUCO_DICT)
    board = cv2.aruco.CharucoBoard((SQUARES_VERTICALLY, SQUARES_HORIZONTALLY), SQUARE_LENGTH, MARKER_LENGTH, dictionary)
    params = cv2.aruco.DetectorParameters()

    # Load PNG images from folder
    image_files = [os.path.join(PATH_TO_YOUR_IMAGES, f) for f in os.listdir(PATH_TO_YOUR_IMAGES) if f.endswith(".png")]
    image_files.sort()  # Ensure files are in order

    all_charuco_corners = []
    all_charuco_ids = []

    for image_file in image_files:
        image = cv2.imread(image_file)
        image_copy = image.copy()
        marker_corners, marker_ids, _ = cv2.aruco.detectMarkers(image, dictionary, parameters=params)
        
        # If at least one marker is detected
        if len(marker_ids) > 0:
            cv2.aruco.drawDetectedMarkers(image_copy, marker_corners, marker_ids)
            charuco_retval, charuco_corners, charuco_ids = cv2.aruco.interpolateCornersCharuco(marker_corners, marker_ids, image, board)
            if charuco_retval:
                all_charuco_corners.append(charuco_corners)
                all_charuco_ids.append(charuco_ids)

    # Calibrate camera
    retval, camera_matrix, dist_coeffs, rvecs, tvecs = cv2.aruco.calibrateCameraCharuco(all_charuco_corners, all_charuco_ids, board, image.shape[:2], None, None)

    # Save calibration data
    np.save('camera_matrix.npy', camera_matrix)
    np.save('dist_coeffs.npy', dist_coeffs)
    fx = camera_matrix[0, 0]
    fy = camera_matrix[1, 1]
    cx = camera_matrix[0, 2]
    cy = camera_matrix[1, 2]
    distortion = dist_coeffs.flatten()
    with open(output, "w") as f:
        f.write("fx: {0}\n".format(fx))
        logging.info("fx: {0}".format(fx))
        f.write("fy: {0}\n".format(fy))
        logging.info("fy: {0}".format(fy))
        f.write("cx: {0}\n".format(cx))
        logging.info("cx: {0}".format(cx))
        f.write("cy: {0}\n".format(cy))
        logging.info("cy: {0}".format(cy))
        for k in range(len(distortion)):
            f.write("k{0}: {1}\n".format(k+1, distortion[k]))
            logging.info("k{0}: {1}".format(k+1, distortion[k]))

    # Iterate through displaying all the images
    for image_file in image_files:
        image = cv2.imread(image_file)
        undistorted_image = cv2.undistort(image, camera_matrix, dist_coeffs)
        cv2.imshow('Undistorted Image', undistorted_image)
        cv2.waitKey(0)

    cv2.destroyAllWindows()

calibrate_and_save_parameters()`

### Fix suggestion

_No response_