FindFundamentalMatrix не находит фундаментальную матрицу - PullRequest
5 голосов
/ 26 июля 2011

Я пытаюсь восстановить движение камеры, используя основную матрицу и алгоритм, приведенный в Википедия .Для этого мне нужно найти фундаментальную матрицу.Я использую OpenCV::findFundamentalMat для этого.

Два неожиданных поведения:

  1. Использование разных алгоритмов подбора дает разные результаты, особенно FM_8POINT отличается.
  2. Учитываянабор пар точек (y, x), yFx = 0 не выполняется и всегда больше 0.

Я что-то здесь не понял?Мой пример неверен или что происходит?Кто-нибудь может предложить лучший тестовый пример?

Ниже приведен минимальный пример.Создайте 12 искусственных точек, сдвиньте каждую из этих точек на 10 пикселей вправо, найдите фундаментальную матрицу из этих двух наборов точек и напечатайте yFx для каждой точки.

Пример:

int main(int argc, const char* argv[])
{
   // Create two sets of points. Points in pts2 are moved 10pixel to the right of the points in pts1.
   std::vector<cv::Point2f> pts1, pts2;
   for(double y = 0; y < 460; y+=150)
   {
           for(double x= 0; x < 320; x += 150)
           {
                   pts1.push_back(cv::Point2f(x, y));
                   pts2.push_back(cv::Point2f(x+10.0, y));
           }
   }

   cv::Mat F = cv::findFundamentalMat(pts1, pts2);

   for(int i = 0; i < pts1.size(); i++)
   {
           // Creating p1, p2, the two points. Please let me know if this can be done in fewer lines.
           cv::Mat p1(3,1, CV_64FC1), p2(3,1, CV_64FC1);

           p1.at<double>(0) = pts1.at(i).x;
           p1.at<double>(1) = pts1.at(i).y;
           p1.at<double>(2) = 1.0;

           p2.at<double>(0) = pts2.at(i).x;
           p2.at<double>(1) = pts2.at(i).y;
           p2.at<double>(2) = 1.0;

           // Print yFx for each pair of points. This should be 0 for all.
           cout << p1.t() * F * p2 << endl;
   }
}

Для FM_RANSAC Я получаю

[1.999], [2], [2], [1.599], [1.599], [1.599], [1.198], [1.198], [1.198], [0.798], [0.798], [0.798]

Для FM_8POINT фундаментальная матрица равна zeros(3,3) и, таким образом, yFx равно 0 для всех y, x.

Я только нашел: Оценка T и R по существенной матрице , но это не очень помогло.

Редактировать : yFx - неправильное решение (p1 / p2 переключено в cout-line).Этот пример также не работает, потому что все точки лежат на плоскости.

Ответы [ 2 ]

3 голосов
/ 26 июля 2011

Я считаю, что фундаментальная матрица решает уравнение p2.t() * F * p1 = 0, т. Е. У вас в коде поменялись местами p1 и p2.Относительно того, почему 8-точечный алгоритм возвращает нулевую матрицу, я понятия не имею, извините.

Редактировать: Хорошо, я полагаю, я помню, почему 8-точечный алгоритм дает плохой результат здесь.Ваше движение между двумя наборами точек составляет чистый перевод без вращения, то есть оно имеет только три степени свободы.Фундаментальная матрица имеет 7 степеней свободы, поэтому ее невозможно оценить;это называется вырожденным случаем.См. этот документ для дальнейшего описания вырожденных случаев в оценке фундаментальной / существенной матрицы.

Может также случиться, что не существует жесткого преобразования между двумя точками зрения, которые вы получаете путем искусственного перемещенияпиксельные координаты, поэтому нет фундаментальной матрицы, удовлетворяющей требованиям.Лучшим тестовым примером может быть использование такой функции, как cv :: warpPerspective с известной матрицей деформации.

1 голос
/ 26 июля 2011

1) Использование разных алгоритмов подбора дает разные результаты, особенно FM_8POINT отличается.

Различные методы не дают одинакового результата, это правда:

  • например, RANSAC (RANdom SAmple Consensus) является методом по умолчанию в findFundamentalMat (), он оценивает параметры преобразования с набором точек, который содержит некоторые случайные точки, которые являются предыдущими выбросами, он дает правильный результат с определенным вероятность.
  • , тогда как FM_8POINT предназначен для поиска параметров с 8 точками и использования системы с линейно независимыми уравнениями.

2) При заданном наборе пар точек (y, x) yFx = 0 не выполняется и является всегда больше 0.

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

Надеюсь, это помогло тебе ... Жюльен

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...