Я пытаюсь восстановить движение камеры, используя основную матрицу и алгоритм, приведенный в Википедия .Для этого мне нужно найти фундаментальную матрицу.Я использую OpenCV::findFundamentalMat
для этого.
Два неожиданных поведения:
- Использование разных алгоритмов подбора дает разные результаты, особенно
FM_8POINT
отличается. - Учитываянабор пар точек (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).Этот пример также не работает, потому что все точки лежат на плоскости.