Всенаправленная калибровка Opencv - PullRequest
1 голос
/ 09 июля 2019

У меня широкоугольный объектив (> 160 градусов).Я попробовал обе модели - Pinhole и Fisheye, и они, кажется, дают четкие выпрямленные изображения с небольшой жертвой FOV.Поэтому я решил попробовать с Всенаправленной моделью.

С Всенаправленной моделью:

double rms = cv::omnidir::stereoCalibrate(Omni_L.RealP, Omni_L.ImageP, Omni_R.ImageP, Omni_L.img.size(), Omni_R.img.size(), K1, xi1, D1, K2, xi2, D2, rvec, tvec, rvecsL, tvecsL, flags, critia);
std::cout << "RMS : " << rms << std::endl;

Я получаю следующие результаты после стереокалибровки

RMS : 0.527522

 Camera_Matrix1 :
 [773.9380049495828, 0, 394.6697338356358;
 0, 776.2094223216956, 382.016762545214;
 0, 0, 1]

 Xi-1 :[1.804945374650817]

 Distortion Parameters1:
 [0, 0, -0.009983732008104793, -0.004530718062523464]

 Camera_Matrix2:
 [783.1807043871861, 0, 393.2120687911561;
 0, 784.4790955477508, 386.7954078861521;
 0, 0, 1]

 Xi-2 :[1.837909340970556]

 Distortion Parameters2:
 [0, 0, -0.009779422171305124, -0.003723193186299092]

 rvec :[-0.003821627764900316;
 0.005567569400892289;
 0.001491183114878044]

 tvec:[-63.09243360480385;
 0.1195353275271446;
 0.9082801155496641]

 R: 
 [1, 0, 0;
 0, 1, 0;
 0, 0, 1]

 P: 
 [773.9380049495828, 0, 394.6697338356358;
 0, 776.2094223216956, 382.016762545214;
 0, 0, 1]

Тогда я делаю искажение:

    cv::Mat R = cv::Mat::eye(3, 3, CV_32FC1);
    cv::Mat Mapx, Mapy;
    cv::Mat P(3, 3, CV_32FC1);
    P = K1;

    cv::Mat orid = cv::imread("Left\\1.jpg");
    std::cout << orid.size();
    std::cout << "R : "<<R<<std::endl;
    std::cout << "P : " << P << std::endl;
    cv::Size s= orid.size();
    try {
        cv::omnidir::initUndistortRectifyMap(K1, D1, xi1, R, P, s, CV_32FC1, Mapx, Mapy, cv::omnidir::RECTIFY_PERSPECTIVE);// Knew, new_size);
        cv::remap(orid, DC, Mapx, Mapy, cv::INTER_CUBIC);
    }
    catch (cv::Exception & e)
    {
        std::cerr << e.msg << std::endl; // output exception message
    }
    std::string Save_Original = "Distorted_Original" + std::to_string(10) + EXT;
    cv::imwrite(Save_Original, orid);
    std::string Save_Corrected = "Distorted_Corrected" + std::to_string(10) + EXT;
    cv::imwrite(Save_Corrected, DC);

Вопрос 1:

Почему радиальное искажение равно нулю?

Вопрос 2:

Вывод изображения без искажений с выпрямлением резко уменьшает FOV.Что-то не так в моем коде?

Исходное изображение: Original Image Изображение с исправленным искажением: Distortion Corrected

Вопрос 3:

Что P и R делают в cv :: omnidir :: initUndistortRectifyMap() функция?

Вопрос 4:

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


Post Trials:

  1. , предложенный @sushi (прокомментированный ниже), чтобы попробовать RECTIFY_CYLINDRICAL для того же изображения и ниже - результат:

    cv::omnidir::RECTIFY_CYLINDRICAL -> Результаты хуже

cv::omnidir::RECTIFY_CYLINDRICAL

1 Ответ

1 голос
/ 09 июля 2019

Сначала я рекомендую вам прочитать этот урок: https://docs.opencv.org/master/dd/d12/tutorial_omnidir_calib_main.html Отвечая на ваши вопросы:

  1. Коэффициенты искажения зависят от выбранной модели искажения.
  2. Посмотрите учебник (часть исправления изображения), если вы хотите сохранить все поля, вам нужно изменить флаг на RECTIFY_CYLINDRICAL
  3. P - «новая» матрица камеры для изображения после выпрямления, R - преобразование вращения между оригиналом и пространством объекта. Вы можете пропустить оба этих параметра, если вы удалите изображения с помощью cv :: omnidir :: undistortImage. Посмотрите в руководстве о рекомендуемых значениях для знал .
  4. Посмотрите на ответ в пункте 2.

Это результат моего подхода с использованием RECTIFY_PERSPECTIVE, я не знаю, почему RECTIFY_CYLINDRICAL не работает в этом случае: This is the result of my approach Чтобы добиться этого, просто удалите ваше изображение так:

cv::Size s = orid.size();
cv::Mat Knew = cv::Mat(cv::Matx33f(s.width / 4, 0, s.width / 2,
        0, s.height / 4, s.width / 2,
        0, 0, 1));
cv::MAt undistorted;
cv::omnidir::undistortImage(orid, undistorted, K1, D1, xi1, cv::omnidir::RECTIFY_PERSPECTIVE, Knew, orid.size());

...