Opencv для Unity — Положение камеры неточно в 2 раза

#camera-calibration #opencv3.1 #aruco #pose

Вопрос:

У меня возникла проблема с получением точной оценки позы аруко. Преобразование объекта AR относительно камеры в ~2 раза меньше, чем должно быть. На скриншоте ниже камера находится на расстоянии z=40 м от маркера в реальном пространстве, но объект AR находится всего в ~20 м в виртуальном пространстве.

Я подумал, что это может быть что-то с параметрами длины, которые я измерил на шахматной доске или маркерами aruco?

Я использовал эти функции:

Aruco.Оцените маркеры (углы, длина маркера, camMatrix, distCoeffs, rvec, tvec);

где Длина маркера = 0,122 м и-расстояние через 4×4 аруко (не включая черную границу)

     private void EstimatePoseCanonicalMarker (Mat rgbMat)
    {
        Aruco.estimatePoseSingleMarkers (corners, markerLength, camMatrix, distCoeffs, rvecs, tvecs);

        for (int i = 0; i < ids.total (); i  ) {
            using (Mat rvec = new Mat (rvecs, new OpenCVForUnity.CoreModule.Rect (0, i, 1, 1)))
            using (Mat tvec = new Mat (tvecs, new OpenCVForUnity.CoreModule.Rect (0, i, 1, 1))) {
                // In this example we are processing with RGB color image, so Axis-color correspondences are X: blue, Y: green, Z: red. (Usually X: red, Y: green, Z: blue)
                Calib3d.drawFrameAxes (rgbMat, camMatrix, distCoeffs, rvec, tvec, markerLength * 0.5f);

                // This example can display the ARObject on only first detected marker.
                if (i == 0) {
                    UpdateARObjectTransform (rvec, tvec);
                }
            }
        }
    }
 

и:

CalcChessboardCorners (размер шаблона, размер квадрата, точка объекта, тип маркера);

где Размер квадрата = .0245 м и-расстояние(м) между 1 квадратом на шахматной доске

     private void CalcChessboardCorners (Size patternSize, float squareSize, MatOfPoint3f corners, MarkerType markerType)
    {
        if ((int)(patternSize.width * patternSize.height) != corners.rows ()) {
            Debug.Log ("Invalid corners size.");
            corners.create ((int)(patternSize.width * patternSize.height), 1, CvType.CV_32FC3);
        }

        const int cn = 3;
        float[] cornersArr = new float[corners.rows () * cn];
        int width = (int)patternSize.width;
        int height = (int)patternSize.height;

        switch (markerType) {
        default:
        case MarkerType.ChessBoard:
        case MarkerType.CirclesGlid:
            for (int i = 0; i < height;   i) {
                for (int j = 0; j < width;   j) {
                    cornersArr [(i * width * cn)   (j * cn)] = j * squareSize;
                    cornersArr [(i * width * cn)   (j * cn)   1] = i * squareSize;
                    cornersArr [(i * width * cn)   (j * cn)   2] = 0;
                }
            }
            corners.put (0, 0, cornersArr);

            break;
        case MarkerType.AsymmetricCirclesGlid:
            for (int i = 0; i < height;   i) {
                for (int j = 0; j < width;   j) {
                    cornersArr [(i * width * cn)   (j * cn)] = (2 * j   i % 2) * squareSize;
                    cornersArr [(i * width * cn)   (j * cn)   1] = i * squareSize;
                    cornersArr [(i * width * cn)   (j * cn)   2] = 0;
                }
            }
            corners.put (0, 0, cornersArr);

            break;
        }
    }
 

Я попытался удвоить некоторые из этих значений и выполнить повторную калибровку, чтобы увидеть, приближается ли значение z к 40 м, но, похоже, оно не меняется . Что заставляет меня чувствовать себя немного невежественным. Я делаю около 50 калибровочных фотографий, и они довольно разнообразны. Я стараюсь зафиксировать диапазон глубины и ракурса на камере.

Есть какие-нибудь идеи?

Спасибо и дайте мне знать, если вам понадобится дополнительная информация.