View Full Version : Specifying translating factor

Mukund

11-16-2010, 07:31 AM

Hello,

i am trying to use IR cameras to move around graphical objects(just a cube) on the screen.

But im not able to get the real world effect, meaning, the cube becomes very small when moved by a certain distance.

Eg: Our hand appear to become small by a certain factor when we move our hands farther(in the real world).

How can i produce the same effect in the virtual world?

Viewing volume:

glFrustum(-500, 500, -500, 500, 100, 2000);

also camera location,

gluLookAt (0, 0, 200.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

Now, i translate the graphic object by a factor of 100 along -Z when the IR source moves 12cm away from the IR camera.

as:

glTranslatef(/* some value */, /*some value */, -z);

But, the object(cube) becomes very small when i do that.

So, how can i adjust the translating factor so that i get the "real world effect" ?

Can anyone please help?

Thanks in advance.

ZbuffeR

11-16-2010, 07:59 AM

Easy !

You have to tweak glFustrum to match your camera intrinsics !

Put your camera on a grid, measure at nearClip distance (100) how much you see to the left and to right, do the same for tom and bottom, and replace the -500,500 values with your actual measurements.

Please, provide some pictures of the results.

EDIT : if you are using a wiimote, read this :

http://www.wiimoteproject.com/wiimote-whiteboard/wiimote-camera-angles/

Mukund

11-16-2010, 09:01 AM

Thanks a lot Zbuffer.

Yes, im using Wiimotes(2 of them to calculate Z)

Well, i do not have a problem with X and Y. Just the Z. For X and Y, im doing this:

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glFrustum(-500, 500, -500, 500, 100, 2000);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt (0, 0, 200.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

int xDiff = abs(xWiiPos[0] - xWiiPos[1]);

xDiff = (xDiff) ? (xDiff) : (1);

x = (position[0][0] / (double)1024) * 1000;

y = (position[0][1] / (double)768) * 1000;

z = (500 / (double)xDiff) * 100; // translate by 500

/* here, position array is used to store values of X and Ys returned by the IR sources. SO, for IR source 0, position[0][0] will have X and position[0][1] will have Y and so on.

So, im mapping the 0-1024 range to -500 to 500(x axis) and similarly on Y axis.

X and Y are in Wiimote resolution (1024 x 768)

im using the difference in the X positions reported by the 2 Wiimotes to find Z.

*/

So, i basically map the 0 to 1024 range of Wiimote to -500 to 500 in the viewing volume. So, no problem wrt X and Y.

However, the Z is not working fine.

Here are the pics:

The right window is the OpenCV window.Please ignore that. Also, the image in the glut window is inverted(have to fix it yet).

1)Z = 12cm

http://img517.imageshack.us/i/89092453.png/

2)Z = 24cm

http://img708.imageshack.us/i/72351217.png/

3)Z = 36cm

http://img600.imageshack.us/i/51153671.png/

As you can see, the cube becomes very small(doesn't look natural)

How can i fix this?

Mukund

11-16-2010, 09:24 AM

Also, i obtained these values:

Candle size(pixels) Size of cube(in pixels)

Z=12 100x100 100x110

Z=24 58x63 50x50

Z=36 40x30 30x20

Approximate reduction in size:

Candle Cube

First movement : 65% 77%

Second movement: 65% 77%

So, i need a 65% size reduction. So what factor can i translate by?

ZbuffeR

11-16-2010, 11:51 AM

Obviously you do not understand basic principles of 3D projection.

Re-read my post above, then follow its instructions, then try to understand why it works, then come back if you have further questions.

Mukund

11-16-2010, 12:42 PM

Thanks!

Could you please explain what i was doing wrong? i did read your post, and i did not quite get what you meant by putting the camera on a grid and measuring.

And, since i was getting the result for the x and y axes, i assumed my method was right and i thought of trying for Z.

i used a library that returns values 0-1024 for the IR source in the X direction. i was mapping these values to obtain values from -500 to 500 and use it to move the graphical cube on the screen.

It would be really helpful if you could please point out my mistake.

ZbuffeR

11-16-2010, 01:34 PM

1)

Ok forget the grid.

Assuming your units are in millimeters, put two candles (C1 and C2) 1000 mm apart (500 minus -500), aim your wiimote right between the candles (middle point M). Then move the wiimote until each candle touches an edge. Now measure distance D between wiimote and point M.

Change frustum like this :

glFrustum(-500, 500, -500, 500, D, far);

You should now have real world values for x,y,z in millimeters.

Do you understand what we did here ?

2) Now for a more practical frustum, let's multiply all that by minimumDistance/D :

glFrustum(-500*minDist/D, 500*minDist/D, -500*minDist/D, 500*minDist/D, minDist, farEnough);

Still good ?

3) NOW WHY YOU MIX 2D PROJECTION COORDINATES (0-1024) WITH 3D WORLD COORDINATES ?

3D is not "lets keep projected x,y and just add z".

When you get X=1024 from your IR lib, it can mean world x=5 for z=10, and x=10 for z=20

Okay ?

So, what to do you have to do, when you know world z, to convert projected x,y to world x,y ? Try to at least find this yourself.

Mukund

11-16-2010, 01:47 PM

Thanks again ZBuffer.

i think you got me wrong. i am using 2 Wiimotes to get the Z from a single IR source.

So, i used a method to find the Z. i use the difference between the X values reported by the Wiimotes to find at what Z distance from the Wiimote the IR source is.

Mukund

11-16-2010, 02:04 PM

Ah, i think i get it. i understood the part about setting up the viewing volume.

Now, using the two Wiimotes, i obtain Z in terms of world. After that, if i have set up the camera right, i will get the proper result when i move the IR source in the Z direction right?

>>So, what to do you have to do, when you know world z, to convert projected x,y to world x,y ? Try to at least find this yourself.

Well, i am currently obtaining the world x,y and using glTranslatef(), i place the object.

Is that fine?

Thanks for the support.

ZbuffeR

11-16-2010, 02:09 PM

How do you get world x,y exactly ?

Mukund

11-16-2010, 02:32 PM

i use the values returned by the Wiimote library. then convert it into world x,y.

ie the wiimote returns 0-1024,

((xReturned / 1024 * 1000) - 500) gives me the world X.

Similary for y also.

Then i translate the object by these values. Is this correct?

ZbuffeR

11-16-2010, 02:49 PM

no as I tried to explain in point 3

http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=286186#Post2861 86

But go ahead, you have to experiment to learn.

Mukund

11-16-2010, 03:05 PM

Hmm, guess i did not follow :(.

Well, thanks anyway, i will read your post again, and try doing it again.

Thanks a lot for the support.

Mukund

11-20-2010, 04:09 AM

Hello ZBuffer,

i followed your suggestions and i obtained the following results.

The candles were separated by a distance of 1280mm, and i got the near clip plane(D) as 1600.

Now,

glFrustum(-640, 640, -480, 480, 1600, 20000);

amd the camera is placed as:

gluLookAt (0, 0, 2000.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

This is how i obtain real world x, y:

The IR camera has 33 and 26 degrees FOV.

double zPos = realZPos; // Z distance in mm

double tempX = zPos * tan(16.5 * (3.14 / 180));

double tempY = zPos * tan(13.0 * (3.14 / 180));

x = (position[0][0] / (double)1024) * (tempX * 2);

y = (position[0][1] / (double)768) * (tempY * 2);

position[0][1] and position[0][0] have the X and Y values returned by the IR library.

here is the calculations i did

http://img99.imageshack.us/i/sampb.png/

Now that i have found x and y, i can translate the object. Have i got it correct now?

Please excuse me if this sounds trivial, i had a course in Computer Graphics and i guess i did not get my basics right. So, im trying to learn now.

Thanks.

ZbuffeR

11-20-2010, 04:14 PM

This looks much better.

How go you get realZPos by the way ? Is that a given, or a measure you get from something ?

Mukund

11-20-2010, 10:46 PM

im using 2 Wiimotes for that. i needed to track a single source(track Z too), which i was not able to do using a single Wiimote.

So, using 2 Wiimotes, the difference of X reported by the Wiimotes is noted. If the IR source goes far, the difference between the reported X(ie the difference between the X values reported by the Wiimotes) becomes less.

i did it on an experimental basis.

ie

if Difference between Xs is around 500, then Z = 2500mm

if Difference between Xs is around 200, then Z = 5000mm

and so on,

This was done on an experimental basis. Right now, im able to measure upto 12500mm from the two Wiimotes.

So, the real world x and y are obtained using this.

double tempX = zPos * tan(16.5 * (3.14 / 180));

So, the zPos here is the measured Z.

So, i need to translate my object based on these x, y, z obtained.

Please correct me if i have gone wrong in any of the steps.

Powered by vBulletin® Version 4.2.3 Copyright © 2017 vBulletin Solutions, Inc. All rights reserved.