Как использовать вектор вращения и перевода OpenCV с OpenGL ES в Android? - PullRequest
12 голосов
/ 14 сентября 2010

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

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

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

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

Ответы [ 2 ]

10 голосов
/ 15 сентября 2010

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

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.Это то, что я нахожу немного странным.Почему только те, а не значения х тоже?

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

2 голосов
/ 16 ноября 2011

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

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

// use the translation vector generated from OpenCV's 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};

Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...