Откалибруйте камеру для определения параметров c - PullRequest
0 голосов
/ 09 апреля 2020

Я изо всех сил пытался сделать правильную калибровку, используя openCV с c ++. Ниже я включил свой фрагмент кода для его вычисления. Буду очень признателен, если вы укажете, что я делаю неправильно, или как я могу его улучшить.

// Initialize and reset calibration params
        void InitCaliberation()
        {
            //numBoards = 0;
            numCornersHor = horizontalCorners;
            numCornersVer = verticalCorners;
            numSquares = horizontalCorners * verticalCorners;

            board_sz = Size(horizontalCorners, verticalCorners);
            frame_sz = Size(frameWidth, frameHeight);
            sqSizeInmm = sqSizemm; //25 mm
            object_points.clear();
            image_points.clear();
            corners.clear();

            finishedCalberation = false;
        }

//Process frames
bool CheckCheckerboardFrame(Mat image, bool debug=false)
        {
            vector<Point3f> obj;
            Mat grayImage;
            cvtColor(image, grayImage, COLOR_BGR2GRAY);

            for (int j = 0; j < numSquares; j++)
                obj.push_back(Point3f(sqSizeInmm * j / numCornersHor, sqSizeInmm * j%numCornersHor, 0.0f));
            bool found = findChessboardCorners(grayImage, board_sz, corners, CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_FILTER_QUADS);

            if (found)
            {
                //sub-pixel accurate location
                cornerSubPix(grayImage, corners, Size(11, 11), Size(-1, -1), TermCriteria(TermCriteria::MAX_ITER | TermCriteria::EPS, 30, 0.1));
                if(debug)
                    drawChessboardCorners(image, board_sz, corners, found);
                else {
                    image_points.push_back(corners);
                    object_points.push_back(obj);
                }
            }

            return found;
        }

// Calculate params
void FinishCaliberation()
        {
            calibrateCamera(object_points, image_points, frame_sz, intrinsic, distCoeffs, R, T);
            finishedCalberation = true;
            cout <<"\nIntrinsic: "<< intrinsic.size<<endl;

            for (int i = 0; i < intrinsic.rows; i++)
            {
                for (int j = 0; j < intrinsic.cols; j++)
                    cout << intrinsic.at<float>(i, j) << " ";
                cout << endl;
            }

            cout << "\nDist coeff: " << distCoeffs.size << endl;
            for (int i = 0; i < distCoeffs.rows; i++)
            {
                for (int j = 0; j < distCoeffs.cols; j++)
                    cout << distCoeffs.at<float>(i, j) << " ";
                cout << endl;
            }
            //cout<<
        }

Ниже приведен вывод, который я получаю с openCV.

output

И это ожидаемый результат. Я рассчитал эту калибровку по Matlab.

expected_output

Я не пытаюсь сопоставить результаты! но хотите понять, почему значения Fy и Cx равны 0 и почему intrinsi c .at (0,1) не равно нулю? и что я тут не так делаю?

вот минимальный код процесса калибровки: http://collabedit.com/3vay2 если кому-то интересно.

1 Ответ

1 голос
/ 09 апреля 2020

Наконец-то разобрался с проблемой. Спасибо - @ Micka

, поэтому я получал значения мусора из-за несоответствия типов данных. Opencv ожидает двойной точности, в то время как я использовал тип float для параметров Mat. Это также стало причиной неожиданных значений, таких как ненулевое значение при intrinsi c .at (0,1).

Что на самом деле заставило меня сомневаться в моей реализации. Но преобразование в двойное исправляет и это. Хотя я не уверен, как двойное значение 0 преобразуется в 6.05179 в float. Может быть связано со скрытой реализацией OpenCV.

...