我无法让charuco相机校准正常工作。据我所知,我做的一切正确,但是最终的未失真图像比预期的要扭曲得多。它确实适用于4x4电路板,但是校正后的面积太小,因此我需要使事情适用于7x7电路板。如果有人可以看到我在做什么,那么非常感谢您的帮助,此刻我有些困惑。所以是这种情况:

我设置了4个摄像头,每个摄像头都需要校准。
每个摄像机我都有11张charuco板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 )

然后依次为每个摄像机的所有图像使用glob模式调用charuco_camera_calib,由于图像的方向正确,因此关闭了图像翻转。

正如我说的,我非常感谢您提供的任何帮助,因为我对这里出了问题不知所措,

乔纳森

*)tutorial_aruco_calibration

最佳答案

好吧,我终于解决了。问题是,如果我可能滥用该术语,则输入图像太“稀疏”。木炭板应覆盖相机的整个视野​​,而不仅仅是中央。将这些图像添加到混合中可以解决此问题。

关于opencv - opencv charuco相机校准无法正确失真,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55689715/

10-12 18:26