Как выполнить калибровку камеры с использованием шахматной доски Charuco для OpenCV 4.10.0?

Вопрос или проблема

Я пытаюсь выполнить калибровку камеры с использованием OpenCV, версии 4.10.0. У меня уже есть рабочая версия для обычной шахматной доски, но я не могу понять, как это работает с charuco. Я был бы благодарен за любой рабочий пример кода.

С наилучшими пожеланиями

Мариус

Что я пробовал: Я следовал этому учебнику: https://medium.com/@ed.twomey1/using-charuco-boards-in-opencv-237d8bc9e40d

Похоже, что отсутствуют важные функции, такие как: cv.aruco.interpolateCornersCharuco и cv.aruco.interpolateCornersCharuco. Даже в документации указана существующая реализация на Python, см.: https://docs.opencv.org/4.10.0/d9/d6a/group__aruco.html#gadcc5dc30c9ad33dcf839e84e8638dcd1

Я также пробовал следовать официальной документации для C++, см. https://docs.opencv.org/4.10.0/da/d13/tutorial_aruco_calibration.html

У ArucoDetector в Python нет метода detectBoard. Поэтому невозможно полностью следовать этому учебнику.

Но я предполагаю, что по намеку в документации функции, использованные в Medium, устарели? Но нигде не отмечены как «удаленные»!

Я уже получил обнаруженные маркеры:

Обнаруженное изображение.

Но затем получить объект и точки изображения не удается:

`object_points_t, image_points_t = charuco_board.matchImagePoints( marker_corners, marker_ids)`

Любая помощь или рабочий код будут весьма оценены.

P.S.: Мой вывод метода “detectMarkers” кажется действительным. Обнаруженные углы имеют тип

std::vector<std::vector<Point2f>.

(Таким образом, переведено на Python как массив массивов, содержащий 4 точки с 2 координатами каждая.) ID — это

std::vector<int>

так что в Python это список целых чисел.

Так что я полагаю, что функция python “matchImagePoints” получает то, что ей нужно!

Обнаружение маркеров, похоже, успешно. Я уже пробовал изменить массив углов: метод detectMarkers возвращает кортеж. Я использовал следующий код, чтобы создать желаемый массив формы (X, 4, 2). (X — это количество обнаруженных маркеров. Каждый имеет 4 угла с 2 координатами x и y.)

marker_corners = np.array(marker_corners)
marker_corners = np.squeeze(marker_corners)

Таким образом, у меня есть следующее:

marker_corners = [
[[8812. 5445.]
[8830. 5923.]
[8344. 5932.]
[8324. 5452.]],

[[7172. 5469.]
[7184. 5947.]
[6695. 5949.]
[6687. 5476.]],

[[3896. 5481.]
[3885. 5952.]
[3396. 5951.]
[3406. 5483.]],
...
]

marker_ids = [
[11],
[27],
[19],
...
]

Оба варианта, передача оригинального результата, который я получаю от

detector.detectMarkers

в функцию и передача моего измененного массива, терпят неудачу. (Также не использование squeeze и ввод массива (X, 1, 4, 2) не удается!)

Я больше не могу продвинуться.

Минимальный рабочий пример:

Используйте это изображение: Charuco board 11x8

    import cv2 as cv
    import numpy as np

    image = cv.imread("charuco_board.png")
    im_gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    charuco_marker_dictionary = cv.aruco.getPredefinedDictionary(cv.aruco.DICT_6X6_250)
    charuco_board = cv.aruco.CharucoBoard(
        size=(11, 8),
        squareLength=500,
        markerLength=300,
        dictionary=charuco_marker_dictionary
    )
    params = cv.aruco.DetectorParameters()
    detector = cv.aruco.ArucoDetector(charuco_marker_dictionary, params)
    marker_corners, marker_ids, rejected_candidates = detector.detectMarkers(im_gray)
    marker_corners = np.array(marker_corners)
    marker_corners = np.squeeze(marker_corners)
    print(marker_corners, marker_ids)
    try:
        object_points_t, image_points_t = charuco_board.matchImagePoints(
            marker_corners,
            marker_ids
        )
    except cv.error as err:
        print(err)

Ответ или решение

Для калибровки камеры с использованием Charuco-доски в OpenCV 4.10.0 необходимо учесть несколько ключевых аспектов. Давайте разберемся, как правильно выполнить эту задачу, используя корректный подход и примеры кода.

Подготовка

Перед началом убедитесь, что у вас установлена библиотека OpenCV версии 4.10.0 с поддержкой ArUco. Это можно сделать с помощью следующей команды pip:

pip install opencv-python==4.10.0 opencv-contrib-python==4.10.0

Пример кода для калибровки камеры с использованием Charuco-доски

Ниже представлен пример кода, который демонстрирует процесс калибровки камеры с использованием Charuco-доски:

import cv2 as cv
import numpy as np

# Определение параметров Charuco-доски
squares_x = 11  # количество квадратов по горизонтали
squares_y = 8   # количество квадратов по вертикали
square_length = 0.04  # длина стороны квадрата в метрах
marker_length = 0.03   # длина стороны маркера в метрах

charuco_dict = cv.aruco.getPredefinedDictionary(cv.aruco.DICT_6X6_250)
charuco_board = cv.aruco.Charucoboard_create(squares_x, squares_y, square_length, marker_length, charuco_dict)

# Параметры детектора
detector_params = cv.aruco.DetectorParameters_create()

# Списки для хранения точек
all_object_points = []
all_image_points = []

# Загрузка изображений с Charuco-доской для калибровки
image_files = ['path_to_image1.jpg', 'path_to_image2.jpg']  # здесь укажите ваши изображения

for file in image_files:
    image = cv.imread(file)
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)

    # Детектирование маркеров
    marker_corners, marker_ids, rejected_candidates = cv.aruco.detectMarkers(gray, charuco_dict, parameters=detector_params)

    if marker_ids is not None:
        # Интерполяция углов Charuco
        retval, charuco_corners, charuco_ids = cv.aruco.interpolateCornersCharuco(marker_corners, marker_ids, gray, charuco_board)

        if retval > 0:
            # Добавление объектных и изображенческих точек
            all_object_points.append(charuco_board.chessboardCorners)
            all_image_points.append(charuco_corners)

# Калибровка камеры
ret, camera_matrix, dist_coeffs, rvecs, tvecs = cv.calibrateCamera(all_object_points, all_image_points, gray.shape[::-1], None, None)

# Сохранение матрицы камеры и коэффициентов искажения
np.savez("camera_calibration.npz", ret=ret, camera_matrix=camera_matrix, dist_coeffs=dist_coeffs)

print("Калибровка завершена!")
print("Матрица камеры:\n", camera_matrix)
print("Коэффициенты искажения:\n", dist_coeffs)

Объяснение кода

  1. Импорт библиотек: Импортируются необходимые библиотеки, включая OpenCV и NumPy.
  2. Создание Charuco-доски: Устанавливаются параметры Charuco-доски, такие как количество маркеров, размеры и длины сторон.
  3. Параметры детектора: Устанавливаются параметры для детектирования маркеров.
  4. Обработка изображений: Загружаются изображения с Charuco-доской. Для каждого изображения:
    • Изображение конвертируется в градации серого.
    • Детектируются маркеры.
    • Интерполируются углы Charuco из обнаруженных маркеров.
    • Если найдены углы, они добавляются в списки изображенческих и объектных точек.
  5. Калибровка камеры: Вызов функции calibrateCamera() для получения матрицы камеры и коэффициентов искажения.
  6. Сохранение результатов: Результаты калибровки сохраняются в файл для дальнейшего использования.

Примечания

  • Убедитесь, что изображения содержат достаточно маркеров, чтобы успешно интерполировать углы Charuco.
  • Возможно, вам потребуется настроить параметр marker_length в зависимости от ваших изображений.
  • Проверяйте, что изображения, использованные для калибровки, имеют хорошее освещение и четкие маркеры.

В случае возникновения вопросов или необходимости в разъяснениях, пожалуйста, не стесняйтесь спрашивать. Удачи в ваших начинаниях!

Оцените материал
Добавить комментарий

Капча загружается...