У меня проблемы с настройкой калибровки камеры charuco. Насколько я знаю, я все делаю правильно, но окончательные неискаженные изображения намного более искажены, чем ожидалось. Он работает с доской 4x4, но тогда выпрямляемая область слишком мала, поэтому мне нужно заставить все работать с доской 7x7. Если есть кто-то, кто может видеть, что я делаю неправильно, помощь очень ценится, я немного застрял на данный момент. Итак, вот случай:
У меня есть 4 камеры, каждая из которых должна быть откалибрована.
У меня есть 11 изображений платы Чаруко 7x7_1000 для каждой камеры, так что всего 44 изображения
это необработанные изображения (для всех камер):
Из того, что я понял в этом уроке *, не все маркеры должны быть видны для калибровки камеры charuco (что и является полной идеей для charuco bord). Насколько я могу судить, исходные изображения в порядке .
Я получаю маркеры и интерполированные углы шахматной доски для набора изображений для каждой камеры и передаю их в функцию v2.aruco.calibrateCameraCharuco. Все выглядит хорошо, так как это изображение со всеми, кроме одного маркера показывает:
Итак, я продолжаю вызывать функцию cv2.undistort, но результат не тот, который я ожидаю:
это код, который я написал, основываясь на примерах из учебника:
def draw_charuco_board( filename, board, size=(2000, 2000) ):
imboard = board.draw(size)
cv2.imwrite(filename, imboard)
def detect_charuco_corners( full_board_image_gray, board ):
parameters = cv2.aruco.DetectorParameters_create()
return cv2.aruco.detectMarkers(full_board_image_gray, board.dictionary, parameters=parameters)
def charuco_camera_calib( board, filename_glob_pattern, do_flip=False, flip_axis=0 ):
"""
calibrates the camera using the charuco board
@see https://docs.opencv.org/trunk/d9/d6a/group__aruco.html#ga54cf81c2e39119a84101258338aa7383
@see https://github.com/opencv/opencv_contrib/blob/master/modules/aruco/samples/calibrate_camera_charuco.cpp
"""
charuco_corners = []
charuco_ids = []
calib_corners = []
calib_ids = []
fns = glob.glob(filename_glob_pattern)
size = None
for fn in fns:
image = cv2.imread(fn, flags=cv2.IMREAD_UNCHANGED)
image_size = tuple(image.shape[:2][::-1])
if size is None:
size = image_size
elif not image_size == size:
raise RuntimeError( "charuco_camera_calib:images are not the same size. previous: {} last: {}\n\tlast image: {}".format(size,image_size,fn))
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
if do_flip:
image = cv2.flip(image, flip_axis)
corners, ids, _ = detect_charuco_corners( image, board )
charuco_corners.append(np.array(corners))
charuco_ids.append(np.array(ids))
if len(corners):
# refine the detection
for i, corner in enumerate(corners):
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_COUNT, 30, 0.1)
cv2.cornerSubPix(image, corner,
winSize = (10,10),
zeroZone = (-1,-1),
criteria = criteria)
# interpolate to find all the chessboard corners
retval, chessboard_corners, chessboard_ids = cv2.aruco.interpolateCornersCharuco( corners, ids, image, board )
if chessboard_corners is not None and chessboard_ids is not None:
calib_corners.append(np.array(chessboard_corners))
calib_ids.append(np.array(chessboard_ids))
else:
raise RuntimeError( "charuco_camera_calib:could not get any markers from image: {}".format(fn))
retval, camera_matrix, dist_coeffs, rvecs, tvecs = cv2.aruco.calibrateCameraCharuco( np.array(calib_corners), np.array(calib_ids), board, size, None, None )
new_camera_matrix, roi = cv2.getOptimalNewCameraMatrix(
camera_matrix, dist_coeffs, size, 1, size
)
# map_x, map_y = cv2.initUndistortRectifyMap(
# camera_matrix, dist_coeffs, None, new_camera_matrix, size, cv2.CV_32FC1
# )
for i, fn in enumerate(fns):
image = cv2.imread(fn, flags=cv2.IMREAD_UNCHANGED)
image = cv2.aruco.drawDetectedMarkers(image, charuco_corners[i], charuco_ids[i])
image = cv2.drawChessboardCorners(image, (6,6), calib_corners[i], True)
image = cv2.undistort(image, camera_matrix, dist_coeffs)
# image = cv2.remap(image, map_x, map_y, cv2.INTER_LINEAR)
new_fn = fn.replace(".png", "_recified.png")
cv2.imwrite(new_fn, image)
return camera_matrix, dist_coeffs
Доска создана с использованием
charuco_board = calibrate.create_charuco_board( dict_name=cv2.aruco.DICT_7X7_1000, squares_x=7, squares_y=7, square_length=40, marker_size=30 )
и затем вызывается charuco_camera_calib с шаблоном глобуса для всех изображений для каждой камеры по очереди, переворот изображения отключается, поскольку изображения ориентированы правильно.
Как я уже сказал, я бы сильно оценил бы любую помощь, так как я в растерянности от того, что здесь происходит не так,
Jonathan
*) tutorial_aruco_calibration