0

Я пытаюсь определить позу камеры на основе фидуциального маркера, найденного в сцене.Определить положение камеры?

Fiducial: http://tinypic.com/view.php?pic=4r6k3q&s=8#.VNLnWTVVK1E

Текущий процесс:

  1. Использование SIFT для обнаружения особенностей
  2. Использование SIFT для извлечения дескриптора
  3. Использование Flann для согласования
  4. Найти гомография с помощью CV_RANSAC
  5. Идентифицировать углы фидуциального
  6. Определить углы фидуциального в сцене с помощью перспективыTransform()
  7. Нарисуйте линии вокруг углов (т. доказать, что он нашел FIDUCIAL в сцене
  8. калибровки Запуск камеры
  9. результаты калибровки нагрузки (cameraMatrix & distortionCoefficients)

Теперь я пытаюсь выяснить камеру позы. я пытался использовать:

аннулируются solvePnP (Const Mat & objectPoints, Const Mat & imagePoints, Const Mat & cameraMatrix, Const Mat & distCoeffs, Mat & rvec, Mat & tvec, BOOL useExtrinsicGuess = ложь)

где:

  • obectPoints являются координатные углы
  • imagePoints являются координатными углами в сцене
  • cameraMatrix составляет от калибровки
  • distCoeffs составляет от калибровки
  • rvec и tvec должен быть возвращен мне из этой функции

Однако, когда я запускаю это , Я получаю ошибку дампа ядра, поэтому я не уверен, что я делаю неправильно.

Я не нашел очень хорошую документацию по решениюPNP() - я неправильно понял функцию или входные параметры?

Цените вашу помощь

Обновления Вот мой процесс:

OrbFeatureDetector detector; //Orb seems more accurate than SIFT 
vector<KeyPoint> keypoints1, keypoints2; 

detector.detect(marker_im, keypoints1); 
detector.detect(scene_im, keypoints2); 

Mat display_marker_im, display_scene_im; 
drawKeypoints(marker_im, keypoints1, display_marker_im, Scalar(0,0,255)); 
drawKeypoints(scene_im, keypoints2, display_scene_im, Scalar(0,0,255)); 

SiftDescriptorExtractor extractor; 
Mat descriptors1, descriptors2; 

extractor.compute(marker_im, keypoints1, descriptors1); 
extractor.compute(scene_im, keypoints2, descriptors2); 

BFMatcher matcher; //BF seems to match better than FLANN 
vector<DMatch> matches; 
matcher.match(descriptors1, descriptors2, matches); 

Mat img_matches; 
drawMatches(marker_im, keypoints1, scene_im, keypoints2, 
    matches, img_matches, Scalar::all(-1), Scalar::all(-1), 
    vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS); 

vector<Point2f> obj, scene; 
for (int i = 0; i < matches.size(); i++) { 
    obj.push_back(keypoints1[matches[i].queryIdx].pt); 
    scene.push_back(keypoints2[matches[i].trainIdx].pt); 
} 

Mat H; 
H = findHomography(obj, scene, CV_RANSAC); 

//Get corners of fiducial 
vector<Point2f> obj_corners(4); 
obj_corners[0] = cvPoint(0,0); 
obj_corners[1] = cvPoint(marker_im.cols, 0); 
obj_corners[2] = cvPoint(marker_im.cols, marker_im.rows); 
obj_corners[3] = cvPoint(0, marker_im.rows); 
vector<Point2f> scene_corners(4); 

perspectiveTransform(obj_corners, scene_corners, H); 

FileStorage fs2("cal.xml", FileStorage::READ); 

Mat cameraMatrix, distCoeffs; 
fs2["Camera_Matrix"] >> cameraMatrix; 
fs2["Distortion_Coefficients"] >> distCoeffs; 

Mat rvec, tvec; 

//same points as object_corners, just adding z-axis (0) 
vector<Point3f> objp(4); 
objp[0] = cvPoint3D32f(0,0,0); 
objp[1] = cvPoint3D32f(gray.cols, 0, 0); 
objp[2] = cvPoint3D32f(gray.cols, gray.rows, 0); 
objp[3] = cvPoint3D32f(0, gray.rows, 0); 

solvePnPRansac(objp, scene_corners, cameraMatrix, distCoeffs, rvec, tvec); 

Mat rotation, viewMatrix(4, 4, CV_64F); 
Rodrigues(rvec, rotation); 

for(int row=0; row<3; ++row) 
{ 
    for(int col=0; col<3; ++col) 
    { 
     viewMatrix.at<double>(row, col) = rotation.at<double>(row, col); 
    } 
    viewMatrix.at<double>(row, 3) = tvec.at<double>(row, 0); 
} 

viewMatrix.at<double>(3, 3) = 1.0f; 

cout << "rotation: " << rotation << endl; 
cout << "viewMatrix: " << viewMatrix << endl; 

ответ

0

Итак, solvePnP() дает матрицу передачи от кадра в модели (то есть куб) для фотокамеры frame (это называется матрицей вида).

Входные параметры:

  • objectPoints - Массив точек объекта в объекте координатном пространстве, 3XN/NX3 1-канальный или 1xN/Nx1 3-канальный, где N есть число точек. std::vector<cv::Point3f> также может быть передан здесь. Точки являются 3D, но так как они находятся в системе шаблона координат (нормирующих маркера), то установка является плоской, так что Z-координатой каждой точки входа объекта равна 0,
  • imagePoints - Массив соответствующих точек изображения, 2xN/Nx2 1-канальный или 1xN/Nx1 2-канальный, где N - количество точек. std::vector<cv::Point2f> может быть также прошли здесь,
  • intrinsics: камера матрица (фокусное расстояние, главная точка),
  • distortion: коэффициенты искажения, нулевые коэффициенты искажения предполагается, если он пуст,
  • rvec: вектор вращения выходного
  • tvec: выход перевод вектор

Построение матрицы вида что-то вроде этого:

cv::Mat rvec, tvec; 
cv::solvePnP(objectPoints, imagePoints, intrinsics, distortion, rvec, tvec); 
cv::Mat rotation, viewMatrix(4, 4, CV_64F); 
cv::Rodrigues(rvec, rotation); 

for(int row=0; row<3; ++row) 
{ 
    for(int col=0; col<3; ++col) 
    { 
     viewMatrix.at<double>(row, col) = rotation.at<double>(row, col); 
    } 

    viewMatrix.at<double>(row, 3) = tvec.at<double>(row, 0); 
} 

viewMatrix.at<double>(3, 3) = 1.0f; 

Кроме того, вы можете поделиться своим кодом и сообщением об ошибке?

+0

Это находит внешние параметры калибровочной шахматной доски. Я пытался найти позу камеры на основе фидуциального маркера. Или я вас не понимаю? – P3d0r

+0

Хорошо, я вас неправильно понял, извините. Ответ отредактирован. – Kornel

+0

Добавленные части моего кода – P3d0r