Оценка позы: определить правильность вращения и матрицы преобразования

В последнее время я борюсь с проблемой оценки позы с одной камерой. У меня есть несколько 3D-точек и соответствующих 2D-точек на изображении. Затем я использую solvePnP, чтобы получить векторы вращения и перемещения. Проблема в том, как я могу определить, являются ли векторы правильными результатами?

Теперь я использую косвенный способ сделать это:
Я использую матрицу вращения, вектор перевода и трехмерные координаты мира определенной точки, чтобы получить координаты этой точки в системе камер. Тогда все, что мне нужно сделать, это определить, являются ли координаты разумными. Я думаю, что знаю направления осей x, y и z системы камеры.

  • Является ли Camera Center источником системы Camera?
  • Теперь рассмотрим x компонент этой точки. Эквивалентен ли x расстоянию камеры и точке в мировом пространстве в направлении оси X камеры (знак может быть затем определен по точке, расположенной на какой стороне камеры)?

На рисунке внизу показано мировое пространство, а изображенные оси - в системе камер.

========How Camera and the point be placed in the world space=============
   |
   |              
Camera--------------------------> Z axis
   |                |} Xw?
   |                P(Xw, Yw, Zw)
   |              
   v x-axis     

Картинка здесь

Мои результаты rvec и tvec кажутся правильными и неправильными. Для указанной точки значение z кажется разумным, я имею в виду, что если эта точка находится на расстоянии около одного метра от камеры в направлении z, то значение z составляет около 1. Но для x и y, в соответствии с расположением Я думаю, что x и y должны быть положительными, но они отрицательны. Более того, шаблон, обнаруженный на исходном изображении, выглядит следующим образом:

изображение шаблона с использованием функции обнаружения с камеры

Но используя координаты точек, рассчитанные в системе камеры, и внутренние параметры камеры, я получаю изображение, подобное этому:

восстановленное изображение

Цель держит свой образец. Но он двигался снизу справа вверху слева. Я не могу понять почему.

2 ответа

Решение

Теперь я знаю ответы.

  • Да, центр камеры является источником системы координат камеры.

  • Учтите, что координаты в системе камер рассчитываются как (xc,yc,zc). Тогда xc должно быть расстоянием между камерой и точкой в ​​реальном мире в направлении x.

Далее, как определить, правильны ли выходные матрицы?
1. как указывает @eidelen, ошибка обратного проецирования является одним из ориентировочных показателей.
2. Рассчитать координаты точек по их координатам в мировой системе координат и матрицах.

Так почему же я получил неправильный результат (рисунок остался, но переместился в другую область изображения)?
параметр cameraMatrix в solvePnP() представляет собой матрицу, предоставляющую параметры внешних параметров камеры. В матрице камеры вы должны использовать ширину /2 и высоту /2 для cx и cy. Пока я использую ширину и высоту изображения размером. Я думаю, что это вызвало ошибку. После того, как я исправил это и повторно калибровал камеру, все кажется хорошо.

Да, центр камеры является источником системы координат камеры, которая, кажется, следует за этим сообщением.

В случае оценки позы камеры, значение кажется разумным и может быть названо ошибкой обратного проецирования. Это мера того, насколько хорошо ваши результирующие вращение и перемещение отображают 3D-точки на 2D-пиксели. К сожалению, solvePnP не возвращает меру остаточной ошибки. Поэтому нужно вычислить это:

cv::solvePnP(worldPoints, pixelPoints, camIntrinsics, camDistortion, rVec, tVec);

// Use computed solution to project 3D pattern to image
cv::Mat projectedPattern;
cv::projectPoints(worldPoints, rVec, tVec, camIntrinsics, camDistortion, projectedPattern);

// Compute error of each 2D-3D correspondence.
std::vector<float> errors;
for( int i=0; i < corners.size(); ++i)
{
    float dx = pixelPoints.at(i).x - projectedPattern.at<float>(i, 0);
    float dy = pixelPoints.at(i).y - projectedPattern.at<float>(i, 1);
    // Euclidean distance between projected and real measured pixel
    float err = sqrt(dx*dx + dy*dy); 

    errors.push_back(err);
}

// Here, compute max or average of your "errors"

Средняя ошибка обратной проекции откалиброванной камеры может быть в диапазоне 0 - 2 пикселя. Согласно вашим двум фотографиям, это было бы намного больше. Для меня это похоже на проблему масштабирования. Если я прав, вы сами рассчитываете проекцию. Может быть, вы можете попробовать один раз cv::projectPoints() и сравнить.

Когда дело доходит до преобразований, я научился не следовать своему воображению:) Первое, что я делаю с возвращенными rVec и tVec, обычно создает из них матрицу жесткого преобразования 4x4 (я однажды разместил здесь код). Это делает вещи еще менее интуитивно понятными, но вместо этого он компактен и удобен.

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