Click here to Skip to main content
14,643,383 members
Rate this:
Please Sign up or sign in to vote.
See more:
Code from "Learn OpenCV" provides all matrix information needed to calculate 3D position of point captured by both cameras. I was planing to use cvUndistortPoints on both points to calculate disparity and then feed one point coordinates plus disparity to cvPerspectiveTransform to obtain 3D position.

I'm bumping in a problem while trying cvUndistortPoints, despite all parameters being ok (or I hope so) points returned are NaN or QNaN.

I'm creating matrix of points(well one point only as this is all I'm interested in) like that:

typedef struct elem_ {
        float f1;
        float f2;
} elem;
CvMat myMat = cvMat(1,1,CV_32FC2);
CV_MAT_ELEM(myMat,elem, 0, 0).f1 = 100.0f;//this is x position
CV_MAT_ELEM(myMat,elem, 0, 0).f2 = 120.0f;//this is y position

So I hope no error here.

cvUndistortPoints(myMat, myMat, &_M1, &_D1, &_R1, &_M1);
float x = CV_MAT_ELEM(myMat,elem, 0, 0).f1; //this returns NaN 

All matrixes are from original example that works fine I just made them member variables so I could access them in my method. They ware calculated as in here:[^]

I did ask questions on OpenCV forum but I had no replies ever.
Any ideas?
Updated 24-May-10 22:11pm
Rate this:
Please Sign up or sign in to vote.

Solution 1

Ok I found solution for this problem had to clone all matrixes used here as somehow they are getting changed in method im taking them from despite that I could not find where.
Rate this:
Please Sign up or sign in to vote.

Solution 2

I am stuck after this point,
I have a two float point f1,f2.
I need to save them and feed them to cvUndistortPoints and find the (xyd)from left and right frame.
Can you please give me a hint what you did after you had the same problem?

Thanks in advance
mateusz.matyaszek 26-Sep-10 5:06am
Well if you could give more details I could give better answer. Im guessing thats what you need:
//sets data
typedef struct elem_ {
float f1;
float f2;
} elem;

elem data1[1] = { 1.0f };
elem data2[1] = { 1.0f };
CvMat _rightPoint = cvMat(1, 1, CV_32FC2, data1 );
CvMat _leftPoint = cvMat(1, 1, CV_32FC2, data2 );

CV_MAT_ELEM(_rightPoint,elem, 0, 0).f1 = rightPoint.x;
CV_MAT_ELEM(_rightPoint,elem, 0, 0).f2 = rightPoint.y;

CV_MAT_ELEM(_leftPoint,elem, 0, 0).f1 = leftPoint.x;
CV_MAT_ELEM(_leftPoint,elem, 0, 0).f2 = leftPoint.y;

//undistort points
cvUndistortPoints(&_leftPoint, &_leftPoint, m_M1, m_D1, m_R1, m_M1);
cvUndistortPoints(&_rightPoint, &_rightPoint, m_M2, m_D2, m_R2 ,m_M2);

//calculate disparity
float disparity = CV_MAT_ELEM(_rightPoint,elem, 0, 0).f1 - CV_MAT_ELEM(_leftPoint,elem, 0, 0).f1;

//prapares point with (x,y,d) coordinates
typedef struct elem3_ {
float f1;
float f2;
float f3;
} elem3;

elem3 data3[3] = { 1.0f };
CvMat _3point = cvMat(1, 1, CV_32FC3, data3 );
CV_MAT_ELEM(_3point,elem3, 0, 0).f1 = rightPoint.x;
CV_MAT_ELEM(_3point,elem3, 0, 0).f2 = rightPoint.y;
CV_MAT_ELEM(_3point,elem3, 0, 0).f3 = disparity;

//gets parameters for reprojection matrix Q
float Fx_= cvmGet( m_M1, 0, 0 ); // focal length in x direction of the rectified image in pixels
float Fy_= cvmGet( m_M2, 1, 1 ); // focal length in y direction of the rectified image in pixels
float Tx_= cvmGet( m_T, 0, 0 ); // Translation in x direction from the left camera to the right camera
float Clx_= cvmGet( m_M1, 0, 2 ); // x coordinate of the optical center of the left camera
float Crx_= cvmGet( m_M2, 0, 2 ); // x coordinate of the optical center of the right camera
float Cy_= cvmGet( m_M1, 1, 2 ); // y coordinate of the optical center of both left and right cameras

float Q[]=
1, 0, 0, -Clx_,
0, 1, 0, -Cy_,
0, 0, 0, (Fx_+Fy_)/2,
0, 0, -1/Tx_, (Crx_-Clx_)/Tx_

CvMat m_Q= cvMat( 4, 4, CV_32F, Q );

//calculates 3D position of marker
cvPerspectiveTransform(&_3point,&_3point, &m_Q);
mismõttes 15-Jan-11 15:54pm
Hey, do you happen to use calibration in your project? I've run out of ideas how to get my stuff running and as you yourself have experienced the opencv list is the worst ever.
Member 11703426 19-May-15 15:02pm
The results are in cm?And wich is the reference system?
Rate this:
Please Sign up or sign in to vote.

Solution 3

Thank you very much.You are a life saver.Its exactly what i needed.

But In
cvUndistortPoints(&_leftPoint, &_leftPoint, m_M1, m_D1, m_R1, m_M1);

Why you use "m_M1" twice?

Should it not be the P1 in the end?
mateusz.matyaszek 28-Sep-10 3:07am
Ha I think I have read this somewhere in OpenCV book but how valid that is I don't know.
My solution was working but I had problem with distance measure not groving linear way eg. at 10cm it was showing 10 at 20cm 30 at 40cm 90 etc. Maybe thats the reason.
What is P1 anyway?
mateusz.matyaszek 28-Sep-10 3:18am
Ok P is "new camera matrix" - which doesn't explain anything. I guess thats why I have used camera matrix M. If you find explanation whats the difference please post it here.
Rate this:
Please Sign up or sign in to vote.

Solution 4

i got p1 and p2 from calibration using Bouguet method.
Without new camera matrix the result is like yours not linear.
But as soon as i use p1 the result is much reliable.
For 100cm im getting around 110 to 122cm
for 200cm im geeting 204 around to 221cm

I am surprised by my result.
Rate this:
Please Sign up or sign in to vote.

Solution 5

Hi hasanm321,

I performed the perspective transformation to 3D coordinates (X,Y,Z). The height,Y and distance,Z coordinates are fairly accurate. But the X coordinate is not what I expect. For a point that is about 1 meter to the right of the Left camera, I get X coordinate of -0.04meter. Did you have this problem? What is the X coordinate relative to?
Thanks for your help

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100