При калибровке камеры обнаружена высокая ошибка на больших изображениях с объективом с большим фокусным расстоянием - PullRequest
1 голос
/ 15 мая 2019

Я новичок здесь, и если я нарушил какое-либо правило, пожалуйста, помогите мне улучшить.

Я делаю некоторую работу по визуальной локализации с рабочим радиусом около 300 м.Поэтому я использую большую камеру с разрешением 4912 * 3684.Но моя калибровка камеры с шахматной доской приводит к высокой ошибке перепроецирования, превышающей 3,6 пикселя.Camera_matrix:

[ 3.0126352098515147e+05, 0., 2456.,
 0., 4.3598609578377334e+05, 1842.,
 0., 0., 1. ]

Я понял, что fx далеко от fy.И номинальный размер пикселя составляет 1,25 мкм, фокусное расстояние составляет 755 мм.И я ссылаюсь на некоторые предложения из этого вопроса FindChessboardCorners не может обнаружить шахматную доску на очень больших изображениях с помощью объектива с большим фокусным расстоянием

Вероятный правильный путь - начать с более низкого разрешения(т.е. уменьшение), затем масштабируйте позиции найденных углов и используйте их в качестве начальных оценок для прогона cvFindCornersSubpix с полным разрешением.

Поэтому я изменяю размер входного изображения до cv::findChessboardCorners() как показано ниже:

    cv::Size msize(1228, 921);  //for resolution 4912*3684
    int downsize = 4;       //downsize scale factor
    cv::Mat small;     // temp file to downsize the image
    cv::resize(imageInput, small, msize);
    bool ok = findChessboardCorners(small, board_size, image_points, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_NORMALIZE_IMAGE);
    if(ok){
        //rectify the corner
            for (size_t j = 0; j < image_points.size(); j++)
            {
                image_points[j].x = image_points[j].x * downsize;
                image_points[j].y = image_points[j].y * downsize;
            }

            Mat view_gray;
            cout << "imageInput.channels()=" << imageInput.channels() << endl;
            cvtColor(imageInput, view_gray, CV_RGB2GRAY);

            cv::cornerSubPix(view_gray, image_points, cv::Size(11, 11), cv::Size(-1, -1), cv::TermCriteria(CV_TERMCRIT_ITER + CV_TERMCRIT_EPS, 40, 0.01));

            image_points_seq.push_back(image_points); 
    }
double err_first = calibrateCamera(object_points_seq, image_points_seq, image_size, cameraMatrix, distCoeffs, rvecsMat, tvecsMat, CV_CALIB_FIX_K3 | CALIB_FIX_PRINCIPAL_POINT);

А вот мои входные изображения: изображения для калибровки

Скажите, пожалуйста, как получить точный результат калибровки!!!

1 Ответ

0 голосов
/ 15 мая 2019

Чтобы любая калибровка была точной, вы должны попытаться учесть следующее:

Убедитесь, что фокусировка правильная, проверив ее с помощью простой диаграммы фокусировки.Окружающая среда имеет значение, сцена должна быть менее отражающей.Калибровка зависит от используемой вами диаграммы фокусировки.Поэтому крайне важно, чтобы фокусная диаграмма была плоской.Любые выпуклости уровня миллиметра также влияют на калибровку.Подумайте о покрытии углов, чтобы получить лучшие коэффициенты искажения.Используйте разные положения шаблона, чтобы покрыть максимум поля зрения.

Помимо всего этого, получите ошибку калибровки для отдельных изображений, и вы сможете наблюдать, какое изображение имеет больше ошибок, а какое - хорошее.Нефокусированные изображения и размытые изображения следует просто выбросить для процесса калибровки.Это простой процесс, если вы дадите пациенту время.Хорошо проведите время калибровки.

...