Ask Your Question
2

Computing attitude(roll, pitch & yaw) from solvePnP()

asked 2013-07-16 04:51:06 -0600

alfa_80 gravatar image

updated 2013-07-16 11:06:38 -0600

I am using solvePnP() to compute for attitude(roll, pitch & yaw). From solvePnP() I got the rotation vector and I use this to accordingly get roll, pitch and yaw. But the problem is when I rotate the camera 45deg, the measurement gives 25deg.

I think, it might be that I need to integrate the angle value(each roll, pitch & yaw ) over time..am I right, integrating it will resolve the issue?

Thanks in advance.

EDIT

The code snippet:

pose[3] = -rot_vec.at(0);

pose[4] = -rot_vec.at(1);

pose[5] = -rot_vec.at(2);

Note: pose[] is roll, pitch & yaw respectively & rot_vec is raw value of rotation vector obtained from solvePnP()

edit retag flag offensive close merge delete

Comments

You should check if there is either a constant error on your measurements, like always 20 degrees, or if it only applies to the single angle. Also, without sharing code with people on how you calculate it, it is actually quite difficult to say what went wrong :)

StevenPuttemans gravatar imageStevenPuttemans ( 2013-07-16 06:54:34 -0600 )edit

@StevenPuttemans: Thanks for the information. I've appended the code snippet in the question.

alfa_80 gravatar imagealfa_80 ( 2013-07-16 11:08:13 -0600 )edit

The output given by solvePnP is the axis-rotation values for the orientation, not eulerangles. They are three elements because opencv uses the reduced notation, being three values to define the rotation axis, and the module of the resultant vector to define the rotation value.

goe gravatar imagegoe ( 2018-02-02 09:15:59 -0600 )edit

2 answers

Sort by » oldest newest most voted
5

answered 2015-01-13 07:59:28 -0600

Haris gravatar image

updated 2015-01-13 08:02:14 -0600

As @StevenPuttemans says, the out put of solvePnP() is not directly roll, yaw & pitch, but need to calculate using rotation matrix.

I also came through the same problem and found the function decomposeProjectionMatrix which gives euler angles as it's output.

Suppose we already get the rotation Mat from solvePnP()

solvePnP(..,...,rotCamerMatrix,transMatrix,false);
Rodrigues(rotCamerMatrix,rotCamerMatrix1);

Now using the function,

void getEulerAngles(Mat &rotCamerMatrix,Vec3d &eulerAngles){

    Mat cameraMatrix,rotMatrix,transVect,rotMatrixX,rotMatrixY,rotMatrixZ;
    double* _r = rotCamerMatrix.ptr<double>();
    double projMatrix[12] = {_r[0],_r[1],_r[2],0,
                          _r[3],_r[4],_r[5],0,
                          _r[6],_r[7],_r[8],0};

    decomposeProjectionMatrix( Mat(3,4,CV_64FC1,projMatrix),
                               cameraMatrix,
                               rotMatrix,
                               transVect,
                               rotMatrixX,
                               rotMatrixY,
                               rotMatrixZ,
                               eulerAngles);
}

Call it like,

   Vec3d eulerAngles;
   getEulerAngles(rotCamerMatrix1,eulerAngles);

where

yaw   = eulerAngles[1]; 
pitch = eulerAngles[0];
roll  = eulerAngles[2];
edit flag offensive delete link more

Comments

Thanks for the answer. I was looking for that and found your answer.

yeser gravatar imageyeser ( 2018-08-13 10:30:57 -0600 )edit

Can you explain more about elements of projMatrix? How to build projMatrix? Thank you.

mado gravatar imagemado ( 2020-05-01 02:12:47 -0600 )edit

Hi @mado, you can build the projection matrix by three things. - The camera matrix (3x3). - The rotation matrix (3x3). - The camera centre wrt the world.

  • You can get the Rotation matrix ( R ) by using the Rodrigues function.
  • You can get the Camera center from this operation --> - R_inverse*Tvec.
  • Once done refer to this link](http://)

    and fill the corresponding matrix, once you multiply both the matrices, you will end up with a projection matrix.!

Chetan_Patil gravatar imageChetan_Patil ( 2020-06-02 06:30:47 -0600 )edit
1

answered 2013-07-17 02:40:06 -0600

I think that what you doing wrong is considering that these angles are actually the exact values for roll, yaw & pitch. Looking at the documentation, the description states:

rvec – Output rotation vector (see Rodrigues() ) that, together with tvec , brings points from the model coordinate system to the camera coordinate system.

tvec – Output translation vector.

This means that for each point you have in your model, you can switch to the camera coördinate system. However, this is NOT the world coördinate system. I think you should still do a second operation to transfer between the camera coordinate system and the world coordinate system.

Maybe take a look at some topics that do exactly what you want, retrieving pitch yaw and roll.

  1. http://www.morethantechnical.com/2010/03/19/quick-and-easy-head-pose-estimation-with-opencv-w-code/
  2. http://planning.cs.uiuc.edu/node103.html
edit flag offensive delete link more

Question Tools

Stats

Asked: 2013-07-16 04:51:06 -0600

Seen: 16,805 times

Last updated: Jan 13 '15