Apriltags3, как я могу улучшить неопределенность позы, когда маркер стоит перед камерой? - PullRequest
0 голосов
/ 07 февраля 2020

У меня есть приложение на c ++, которое использует фидуциальные маркеры Apriltags3.

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

в этих случаях поза значительно меняется, делая данные позы непригодными для использования. Как я понимаю, это переворот - известная проблема с квадратными маркерами, поскольку есть два возможных решения для оценки позы.

Как я могу улучшить это переворот? Я попытался:

1 - Используя SolvePnp с флагом IPPE_SQUARE, я могу вернуть оба решения.

std::vector<cv::Vec3d> rvecsVec, tvecsVec;
std::vector<double> errs;
solvePnPGeneric(markerObjPoints, marker.corners2d, K, D, rvecsVec, tvecsVec, false, cv::SOLVEPNP_IPPE_SQUARE, cv::noArray(), cv::noArray(),errs);

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

2 - сохранение предыдущих нескольких поз и выполнение регулировки связки скользящего окна на 3-х точках, 2d углы и позы. Это, кажется, не имеет никакого эффекта, и я все еще вижу тот же переворот.

3 - Использование следующего:

cv::Mat R1;
cv::Rodrigues(rvecsVec[0], R1);
R1 = R1.t();
cv::Mat t1 = -R1 * tvecsVec[0];

cv::Mat R2;
cv::Rodrigues(rvecsVec[1], R2);
R2 = R2.t();
cv::Mat t2 = -R2 * tvecsVec[1];

Чтобы получить позы камеры относительно маркеров. Я бы предположил, что поза камеры с положительным значением X (перед маркером) будет правильной, однако, когда я использую эту позу:

if (t1.at<double>(0, 0) < 0)
    {
        marker.rvec = rvecsVec[0];
        marker.tvec = tvecsVec[0];
        std::cout << "using pose 0" << std::endl;

    }
    if (t2.at<double>(0, 0) < 0)
    {
        marker.rvec = rvecsVec[1];
        marker.tvec = tvecsVec[1];
        std::cout << "using pose 1" << std::endl;       
    }

Я вижу ту же проблему, что и с решение 1.

4 - используя стереокамеру, найдите маркеры в каждом кадре, триангулируйте точки и затем используйте функцию Eigen SVD, чтобы найти жесткое преобразование между этими точками и набором точек, созданных из длины маркера в ноль.

PointsType p1s, p2s;
p1s.push_back(Eigen::Vector3d(-markerLength / 2.f, markerLength / 2.f, 0));
p1s.push_back(Eigen::Vector3d(markerLength / 2.f, markerLength / 2.f, 0));
p1s.push_back(Eigen::Vector3d(markerLength / 2.f, -markerLength / 2.f, 0));
p1s.push_back(Eigen::Vector3d(-markerLength / 2.f, -markerLength / 2.f, 0));

Это прекрасно работает для перевода, но вращение, кажется, переворачивается еще больше!

Есть ли ответ для этого? Что еще я могу попробовать?

Примечание: я проверил с маркерами Aruco, той же камерой и калибровкой, и я не вижу этой проблемы с переворотом, это похоже на проблему с Apriltags3.

...