The second aspect which is almost as important is registration, or getting your graphics to line up correctly with the real world. Without this, your graphic augmentations could be useless, or worse, could lead to errors.
There are all sorts of advanced calibration techniques available. On our SGI systems, we have implemented a semi-automatic calibration system. I didn't do that work; you'll have to wait for Anu Rastogi to write all of his brilliant work down before you can read about that. Send him e-mail to bug him about at anu@argos.rose.utoronto.ca.
In this document, I only talk about the manual calibration technique I used with my original Amiga-based system. While somewhat old-fashioned, enough people need to do this that I thought it would be worth sharing it with you.
These instructions were written for people using my software in particular, but the general procedures are what should interest you.
In order to draw the virtual pointer in a calibrated way, the program needs to know certain things about the camera configuration. It gets this information by reading a file called cursor.init, which looks like this:
SEPARATION 0.12 CONVERGENCE 1.00 FOCALLENGTH 0.006 CHIPHEIGHT 0.004817 CHIPWIDTH 0.005467 THREADX 0.0 THREADY 0.2 THREADZ 0.0 CURSIZE 0.1 XSPEED 0.001 YSPEED 0.001 ZSPEED 0.001 PATTERN 0xFFFF
The first two values are the separation between the cameras, and the distance from the cameras to the convergence point. The procedure for measuring these values is given below. The values are in metres, of course. (Inches? What are inches?)
The focal length of the lens is assumed to be correct, so you just type in whatever it says on the lens. Again, this is in metres.
The chip height and chip width are measured by the procedure described below in Part 2. Together with the focal length, these determine the field of view NOT for the camera, but for that portion of the CCD that corresponds to the Amiga graphics. The Amiga graphics do not cover the whole screen; there is a border around the edges that is not usable. (I might have been able to shrink this border using a technique known as overscan, but I didn't have much luck, and the only documentation that was available then was version 1.0, which was awful and full of errors, so I just gave up.) So by using the procedure mentioned below, you can determine the size of the correponding region.
The thread x, y, and z values are not used in the current version. They are meant to specify the anchor point of a "thread" that always stretches to the cursor. Paul Milgram thought that this would be a useful cue. I didn't, so I didn't implement it, but I put the hooks in because I figured I would try it some day.
The cursor size value gives the height of the virtual pointer, measured in metres. The arrow shaped pointer typically used is 10 cm high and 20 cm wide, but if you have very small lenses or are working far away, you can make the cursor larger.
The X, Y, and Z speeds refer to the gain between steps (or pulses) of the input device (we used a FastTrap, which was a combination of a trackball for X and Y, and a thumbwheel for Z), and the distance the virtual pointer moves. A value of .001 means that the cursor moves 1 mm for each step of the FastTrap.
Finally, the pattern value is the fill pattern used for drawing the virtual pointer, and is a 2-bye unsigned integer. 0xFFFF means that a solid pattern is used, so that the cursor is opaque. 0x5555 means that every other pixel is drawn, so that you can see through the pointer somewhat. It isn't the same as being transparent, but it looks okay, and is all that was possible with the Amiga 500 I was using.

We want to know two things: distance "s" (which is half the separation between the cameras), and distance "d", which is part of the distance to the object. These can be calculated readily enough if you know "b", which we do (because we can measure the object and divide by 2), and "a" and "c", which we measure.
The way to measure "a" and "c" is as follows:
(1) Set your cameras up carefully, so that they are symetrically aligned with Obect A. Make certain that Object A is centred on their cyclopean line-of-sight (i.e. on their principal axis). You will have to invest several hours into this, and will need long straight objects to look down the length of in order to make certain that you are right.
(2) Place a real pointer (NOT the virtual one, although it should be possible to do this with that, but I haven't figured out the math yet) of some kind at the centre of object a, so that it looks something like Figure 2 on the monitor without glasses. (It doesn't have to be identical by any means, but something along those lines.) Then, bring the pointer along the principal axis towards the cameras. You will see a doubled image of the pointer, looking something like Figure 3. Measure the distance "c" from the tip of the pointer to the centre of the object.
(3) Repeat the process, but this time behind the object, so that the image on the screen looks like Figure 4. Measure distance "a".
Repeat this process at least 10 times. You should end up with slightly different measures each time, due to the imprecise display. This is normal and appropriate, and is why you are repeating the measure. Do not try to be consistent in real space (i.e. do not position the pointer based on the previous position); you want each measurement to be independent of the previous ones, and based only on the view on the monitor.

Once you have your measures and are satisfied that you did everything correctly, calculate the mean scores and standard deviations. If the deviations are relatively small, and you feel confident with continuing, then proceed. Otherwise, adjust things if necessary and make more measurements. Try to get a feel for how large the standard deviation can be by exploring the range of "a" and "c" measurements that look the same on the screen.
Once you have "a", "b", and "c", you can calculate things as follows:
a a + c + d c d
Equation 1: --- = ----------- Equation 2: --- = ---
b s b s
From these, we can solve for "d" and "s" as follows:
a + c a + c
Equation 3: s = b ------- Equation 4: d = c -------
a - c a - c
And since the camera separation is actually 2*s, and since the
convergence distance is actually d+c, we can easily calculate
these values and enter them into the "cursor.init" file.Note also that by carefully measuring the distance "d+c" from the object to the cameras, we can get a good approximation of where the centroid of the camera system is. All measurements made with the virtual pointer are relative to this point.
.....................
Now, carefully place markers of some sort so that they are all carefully in a line. You should only be able to see the one in the very front. (The markers don't have to be fixed into place. You can just use one if you prefer and carefully measure x and z each time you place it.) That's what I did.
Once you've made about 10 to 20 measurements, you can do a nice simple regression analysis to figure out what the ideal lines should be, and from that calculate the the angle alpha. (alpha = atan (x/z), so if you do enough x/z's and take the average, and then take the arctan, you should end up with a reasonable estimate of alpha.)
What you have calculated is half of the field of view. Given the focal length, we can then calculate the width of the CCD, since
tan(alpha) = focal_length / CCD_width
As for the vertical field of view, I can't remember what I did, and all of my documentation for this is in Canada. You will probably do okay if you simply assign chip_y = 0.75 * chip_x.