private double CalibrateCameraCharuco(List <List <Mat> > allCorners, List <Mat> allIds, CharucoBoard board, Size imageSize, Mat cameraMatrix, Mat distCoeffs, List <Mat> rvecs = null, List <Mat> tvecs = null, int calibrationFlags = 0, int minMarkers = 2)
        {
            // prepare data for charuco calibration
            int        nFrames           = allCorners.Count;
            List <Mat> allCharucoCorners = new List <Mat>();
            List <Mat> allCharucoIds     = new List <Mat>();
            List <Mat> filteredImages    = new List <Mat>();

            for (int i = 0; i < nFrames; ++i)
            {
                // interpolate using camera parameters
                Mat currentCharucoCorners = new Mat();
                Mat currentCharucoIds     = new Mat();

                Aruco.interpolateCornersCharuco(allCorners[i], allIds[i], allImgs[i], board, currentCharucoCorners, currentCharucoIds, cameraMatrix, distCoeffs, minMarkers);

                if (charucoIds.total() > 0)
                {
                    allCharucoCorners.Add(currentCharucoCorners);
                    allCharucoIds.Add(currentCharucoIds);
                    filteredImages.Add(allImgs[i]);
                }
                else
                {
                    currentCharucoCorners.Dispose();
                    currentCharucoIds.Dispose();
                }
            }

            if (allCharucoCorners.Count < 1)
            {
                Debug.Log("Not enough corners for calibration.");
                return(-1);
            }

            if (rvecs == null)
            {
                rvecs = new List <Mat>();
            }
            if (tvecs == null)
            {
                tvecs = new List <Mat>();
            }

            return(Aruco.calibrateCameraCharuco(allCharucoCorners, allCharucoIds, board, imageSize, cameraMatrix, distCoeffs, rvecs, tvecs, calibrationFlags));
        }