Python 使用ChArUco对两台摄像机进行OpenCV立体标定

Python 使用ChArUco对两台摄像机进行OpenCV立体标定,python,opencv,computer-vision,camera-calibration,stereo-3d,Python,Opencv,Computer Vision,Camera Calibration,Stereo 3d,我想使用一个图像的多个帧来计算两个相机之间的相对变换([R | t]矩阵)。我的想法是从所有帧中获取图像-对象-点对,然后使用一个函数获取所有检测到的点对,并输出相机之间的相对变换(例如) 最好的方法是什么?我无法让stereoCalibrate工作,因为它总是抛出断言错误-> 当前实施(不起作用): 今天早些时候,我刚刚做了类似的事情。我认为您至少解决了部分问题,因为您关闭了提到的bug。在任何情况下,在我看来,问题在于您传递的是一个点数组,而它应该是一个点数组(具有足够数据的每个帧的点数组)

我想使用一个图像的多个帧来计算两个相机之间的相对变换([R | t]矩阵)。我的想法是从所有帧中获取图像-对象-点对,然后使用一个函数获取所有检测到的点对,并输出相机之间的相对变换(例如)

最好的方法是什么?我无法让stereoCalibrate工作,因为它总是抛出断言错误->

当前实施(不起作用):


今天早些时候,我刚刚做了类似的事情。我认为您至少解决了部分问题,因为您关闭了提到的bug。在任何情况下,在我看来,问题在于您传递的是一个点数组,而它应该是一个点数组(具有足够数据的每个帧的点数组)

另一方面,
cv2.aruco.getBoardObjectAndImagePoints
可能不是您想要的,因为
cornersA
cornersB
已经是图像点(棋盘图案角),对象点(棋盘图案角的位置)可以从aruco标记ID计算,而据我所知,
getBoardObjectAndImagePoints
是关于阿鲁科标记角的


在内部,
cv2.aruco.calibleCameracharuco
仅调用
cv2.calibleCamera
,将传递的角点作为图像点,并调用对象点。不幸的是,从aruco ID获取对象点并没有在API中公开,但它很容易计算:

我今天早些时候做了类似的事情。我认为您至少解决了部分问题,因为您关闭了提到的bug。在任何情况下,在我看来,问题在于您传递的是一个点数组,而它应该是一个点数组(具有足够数据的每个帧的点数组)

另一方面,
cv2.aruco.getBoardObjectAndImagePoints
可能不是您想要的,因为
cornersA
cornersB
已经是图像点(棋盘图案角),对象点(棋盘图案角的位置)可以从aruco标记ID计算,而据我所知,
getBoardObjectAndImagePoints
是关于阿鲁科标记角的

在内部,
cv2.aruco.calibleCameracharuco
仅调用
cv2.calibleCamera
,将传递的角点作为图像点,并调用对象点。不幸的是,从aruco ID获取对象点并未在API中公开,但计算起来非常简单:

imagePointsA = []
imagePointsB = []
objectPoints = []
    for frameA, frameB in color_framesets(...):
        try:            
            # Find corners
            cornersA, idsA, rejected = cv2.aruco.detectMarkers(frameA, charucoDict)
            cornersB, idsB, rejected = cv2.aruco.detectMarkers(frameB, charucoDict)
            if not cornersA or not cornersB: raise Exception("No markers detected")

            retA, cornersA, idsA = cv2.aruco.interpolateCornersCharuco(cornersA, idsA, frameA, charucoBoard)
            retB, cornersB, idsB = cv2.aruco.interpolateCornersCharuco(cornersB, idsB, frameB, charucoBoard)
            if not retA or not retB: raise Exception("Can't interpolate corners")


            # Find common points in both frames (is there a nicer way?)
            objPtsA, imgPtsA = cv2.aruco.getBoardObjectAndImagePoints(charucoBoard, cornersA, idsA)
            objPtsB, imgPtsB = cv2.aruco.getBoardObjectAndImagePoints(charucoBoard, cornersB, idsB)

            # Create dictionary for each frame objectPoint:imagePoint
            ptsA = {tuple(a):tuple(b) for a, b in zip(objPtsA[:,0], imgPtsA[:,0])}
            ptsB = {tuple(a):tuple(b) for a, b in zip(objPtsB[:,0], imgPtsB[:,0])}
            common = set(ptsA.keys()) & set(ptsB.keys())    # intersection between obj points
            
            for objP in common:
                objectPoints.append(np.reshape(objP, (1, 3)))
                imagePointsA.append(np.reshape(ptsA[objP], (1, 2)))
                imagePointsB.append(np.reshape(ptsB[objP], (1, 2)))

        except Exception as e:
            print(f"Skipped frame: {e}")
            continue

    result = cv2.stereoCalibrateExtended(objectPoints, imagePointsA, imagePointsB, intrA, distA, intrB, distB, (848, 480), flags=cv2.CALIB_FIX_INTRINSIC+cv2.CALIB_USE_EXTRINSIC_GUESS)