Подтвердить что ты не робот

Как использовать вектор вращения OpenCV и перевод с OpenGL ES в Android?

Я работаю над базовым дополненным реальным приложением на Android. То, что я сделал до сих пор, - это обнаружить квадрат с opencv, а затем использовать cvFindExtrinsicCameraParams2() Я вычислил вектор вращения и перевода. Для этого я использовал 4 точки объекта, которые являются только углами квадрата вокруг (0,0,0) и 4 углами квадрата изображения.

Это дает мне довольно хорошую матрицу вращения и перевода. Я также вычислил матрицу вращения cvRodrigues2(), так как использование этого проще, чем вектор вращения. Пока я использую их, чтобы нарисовать некоторые точки на изображении, все работает нормально. Однако мой следующий шаг - передать эти векторы и матрицу обратно в java, а затем использовать их с OpenGL для рисования квадрата в OpenGLView. Квадрат должен быть точно вокруг квадрата в изображении, который отображается за OpenGLView.

Моя проблема в том, что я не могу найти правильный способ использования матрицы вращения и вектора перевода в OpenGL. Я начал с точно таких же объектов, что и для функций openCV. Затем я применил матрицу вращения и вектор трансляции практически любым возможным способом, о котором я мог думать. К сожалению, ни один из этих подходов не дает результата, который в любом случае приближается к тому, на что я надеялся. Может ли кто-нибудь сказать мне, как правильно их использовать?

До сих пор "самые близкие" результаты, которые я получил, были при случайном умножении всей матрицы на -1. Но большую часть времени квадраты по-прежнему выглядят зеркально, повернуты или повернуты на 180 градусов. Поэтому я думаю, что это был просто удачный удар, но не правильный подход.

4b9b3361

Ответ 1

Хорошо, после некоторого тестирования я, наконец, смог заставить его работать. Хотя я этого не понимаю... он "работает". Для тех, кому это нужно в будущем, это мое решение.

float rv[3]; // the rotation vector
float rotMat[9]; // rotation matrix
float tv[3]; // translation vector.


rv[1]=-1.0f * rv[1]; rv[2]=-1.0f * rv[2];
//Convert the rotation vector into a matrix here.

//Complete matrix ready to use for OpenGL
float RTMat[] = {rotMat[0], rotMat[3], rotMat[6], 0.0f,
                 rotMat[1], rotMat[4], rotMat[7], 0.0f,
                 rotMat[2], rotMat[5], rotMat[8], 0.0f,
                 tv[0], -tv[1], -tv[2], 1.0f};

Как сказал genpfault в своем комментарии, все должно быть перенесено с OpenGL, так как OpenGL нуждается в упорядоченном столбце. (Спасибо за комментарий, я уже видел эту страницу ранее.) Кроме того, угол поворота y и z, а также перевод y и z необходимо умножить на -1. Это то, что я нахожу немного странным. Почему только те, а не значения x тоже?

Это работает, как я полагаю. Но углы не совпадают точно. Я предполагаю, что это вызвано некоторыми неправильными конфигурациями openGLView. Поэтому, хотя я до сих пор не доволен своим решением на 100%, я думаю, что это ответ на мой вопрос.

Ответ 2

Метод Пандоро действительно работает! В случае, если кто-то задается вопросом "как преобразовать вектор вращения в матрицу вращения" здесь, как я это сделал. Кстати, я использовал их в OpenGL 2, а не в ES.

// use the rotation vector generated from OpenCV cvFindExtrinsicCameraParams2() 
float rv[] = {rotation->data.fl[0], rotation->data.fl[1], rotation->data.fl[2] }; 

// use the translation vector generated from OpenCV cvFindExtrinsicCameraParams2() 
float tv[] = {translation->data.fl[0], translation->data.fl[1], translation->data.fl[2]} ; 

float rm[9];
// rotation matrix
CvMat* rotMat = cvCreateMat (3, 3, CV_32FC1); 

// rotation vectors can be converted to a 3-by-3 rotation matrix
// by calling cvRodrigues2() - Source: O'Reilly Learning OpenCV
cvRodrigues2(rotation, rotMat, NULL);

for(int i=0; i<9; i++){
    rm[i] = rotMat->data.fl[i];
}

rv[1]=-1.0f * rv[1]; rv[2]=-1.0f * rv[2];
//Convert the rotation vector into a matrix here.

//Complete matrix ready to use for OpenGL
float RTMat[] = {rm[0], rm[3], rm[6], 0.0f,
             rm[1], rm[4], rm[7], 0.0f,
             rm[2], rm[5], rm[8], 0.0f,
             tv[0], -tv[1], -tv[2], 1.0f};

Удачи!