Я пытаюсь реализовать solvePnP
, чтобы найти внешние параметры камеры. Я обнаруживаю некоторые точки на изображении с известной позицией 3d и подаю 2 набора точек на solvePnP
.SolvePnP работает нестабильно и сбой
С некоторым набором функций функция работает очень точно, но очень часто, когда я добавляю или удаляю некоторые точки из набора, решение становится полностью неправильным. На самом деле требуется много усилий, чтобы найти, какой набор точек подходит для solvePnP
.
Обнаруживаемые точки не очень точные (+ - 10
пикселей от истинной позиции) - может быть это причина? Но все же с некоторыми наборами он работает отлично.
И еще одна проблема заключается в том, что SolvePnPRansac
и SolvePnP
с CV_P3P
Параметр сбоев бросает исключение памяти.
Вот мой код
vector<cv::Point3d> points3d;
vector<cv::Point2d> points2d;
cv::Mat rvec(3,1,CV_64FC1,Scalar::all(0)) , tvec(3,1,CV_64FC1,Scalar::all(0));
Mat cam_matrix = Mat(3,3,CV_64FC1,Scalar::all(0));
cam_matrix.at<double>(0,0) = 395.;
cam_matrix.at<double>(0,2) = 160.;
cam_matrix.at<double>(1,1) = 395.;
cam_matrix.at<double>(1,2) = 120.;
cam_matrix.at<double>(2,2) = 1.0f;
/*
here is a code for pushing 3d and 2d points to points3d and points2d vectors
*/
cv::solvePnP(points3d, points2d, cam_matrix, Mat(), rvec, tvec, false, CV_ITERATIVE); //very unstable
//cv::solvePnPRansac(points3d, points2d, cam_matrix, Mat(), rvec, tvec, false); // memory exception
//cv::solvePnP(points3d, points2d, cam_matrix, Mat(), rvec, tvec, false, CV_P3P); // memory exception
Большое спасибо.
Я нашел проблемы с флагом СV_P3P. Это потому, что я пропустил слишком много очков (требуется ровно 4). Также для моего случая флаг CV_EPNP для solvePnP работает намного стабильнее, чем с другими, но все же не так много. Функция Ransac должна быть свободной от этой проблемы, но я не могу ее запустить. Он все еще падает. –
Моим решением для решенияPnPRansac было использование Mat вместо вектора. Хотя в документах сказано, что обе версии возможны, в моем случае Mat работает нормально, исключение векторных исключений. Я попробовал как двойной, так и плавающий. Кстати, как и ожидалось, Рэнсак является самым стабильным для выбросов. –