OpenCV: как рассчитать необходимую матрицу из совпадений признаков между двумя изображениями с разных камер с использованием 5-точечного алгоритма?

В основном я хочу сделать то же самое, что и эта функция здесь: https://docs.opencv.org/master/d9/d0c/group__calib3d.html#ga13f7e34de8fa516a686a56af1196247f

Однако в описании параметра указано, что этот алгоритм предполагает, что совпадающие характерные точки двух изображений взяты с камер с одной и той же матрицей камер.

Что, если у меня есть совпадающие функции, но изображения с двух разных камер с разными матрицами камер? Как я могу рассчитать основную матрицу из 5 пунктов?

Дополнительный вопрос: Если я рассчитал основную матрицу, могу ли я просто использовать ее в качестве параметра в методе computeCorrespondEpilines() вместо основной матрицы, предполагая, что изображения уже исправлены?

3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
2
0
3 547
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В OpenCV нет стандартной функции для расчета основной матрицы с использованием двух разных камер. Но это очень легко реализовать самостоятельно. Вы можете добавить функцию в five-point.cpp и перекомпилировать OpenCV. Я просто добавил перегруженную функцию cv::findEssentialMat с дополнительным параметром для матрицы второй камеры.

cv::Mat cv::findEssentialMat(InputArray _points1, InputArray _points2, InputArray _cameraMatrix1, InputArray _cameraMatrix2, int method, double prob, double threshold, OutputArray _mask)
{
    CV_INSTRUMENT_REGION();

    Mat points1, points2, cameraMatrix1, cameraMatrix2;
    _points1.getMat().convertTo(points1, CV_64F);
    _points2.getMat().convertTo(points2, CV_64F);
    _cameraMatrix1.getMat().convertTo(cameraMatrix1, CV_64F);
    _cameraMatrix2.getMat().convertTo(cameraMatrix2, CV_64F);

    int npoints = points1.checkVector(2);
    CV_Assert(npoints >= 0 && points2.checkVector(2) == npoints &&
        points1.type() == points2.type());

    CV_Assert(cameraMatrix1.rows == 3 && cameraMatrix1.cols == 3 && cameraMatrix1.channels() == 1);
    CV_Assert(cameraMatrix2.rows == 3 && cameraMatrix2.cols == 3 && cameraMatrix2.channels() == 1);

    if (points1.channels() > 1)
    {
        points1 = points1.reshape(1, npoints);
        points2 = points2.reshape(1, npoints);
    }

    double fx1 = cameraMatrix1.at<double>(0, 0);
    double fy1 = cameraMatrix1.at<double>(1, 1);
    double cx1 = cameraMatrix1.at<double>(0, 2);
    double cy1 = cameraMatrix1.at<double>(1, 2);
    double fx2 = cameraMatrix2.at<double>(0, 0);
    double fy2 = cameraMatrix2.at<double>(1, 1);
    double cx2 = cameraMatrix2.at<double>(0, 2);
    double cy2 = cameraMatrix2.at<double>(1, 2);

    points1.col(0) = (points1.col(0) - cx1) / fx1;
    points2.col(0) = (points2.col(0) - cx2) / fx2;
    points1.col(1) = (points1.col(1) - cy1) / fy1;
    points2.col(1) = (points2.col(1) - cy2) / fy2;

    // Reshape data to fit opencv ransac function
    points1 = points1.reshape(2, npoints);
    points2 = points2.reshape(2, npoints);

    threshold /= (fx1 + fy1) / 2;

    Mat E;
    if (method == RANSAC)
        createRANSACPointSetRegistrator(makePtr<EMEstimatorCallback>(), 5, threshold, prob)->run(points1, points2, E, _mask);
    else
        createLMeDSPointSetRegistrator(makePtr<EMEstimatorCallback>(), 5, prob)->run(points1, points2, E, _mask);

    return E;
}

Затем вам нужно добавить объявление функции в calib3d.hpp, перекомпилировать и переустановить версию OpenCV.

Additional question: If I have calculated the essential matrix can I just use it as parameter in the method computeCorrespondEpilines() instead of the fundamental matrix, assuming images are already rectified?

Да, я думаю, это должно сработать.

Спасибо за информацию, очень помогает :)

Roland Deschain 23.05.2019 15:59

Другие вопросы по теме