In this writeup, I am going to explain how stereograms work, and give an example of how you could program a computer to produce the effect.
To start with, you need to understand how the human brain perceives depth in real life. Because your eyes are a few inches apart, each eye sends a slightly different image to the brain. The brain aligns the two images, examines the differences between them, and thus works out how far away the various things are. With only one eye, you can still see in quasi-3D because your brain can make comparisons between known object sizes and also note the way objects 'move' across your view when you move your head. So, if you see a person who appears to be bigger than a house, then you know that the house is a certain distance away and the person is nearer. You would also notice how moving your head slightly would have a greater effect on your view of the person than of the house. Overall though, you need both eyes to see in true 3D. Try playing 'catch' with one eye closed and you'll agree.
So, onto stereograms. Assuming you've seen one, you'll be aware that there is a horizontally repeating pattern. The essence of 'seeing' a stereogram in 3D is convincing your brain to miss-match the sets of patterns when it combines the images from your two eyes. This is not easy to explain, but a diagram may help:
0 1 2 3 4 5
* * * * * *
* * * * * *
* * * * * *
* * * * * *
Imagine that the columns of stars above are the columns of repeating pattern in your stereogram. When you look at them, both eyes send five columns of stars to your brain, and normally, your brain accurately works out how far away they are from you. However, if you do all that 'stare through the picture' stuff and thus diverge your eyes, you can trick your brain into misinterpreting the two images it receives.
The brain is tricked into mismatching the pictures from each eye so that it matches the left eye's column 1 with the right eye's column 2, the left eye's column 2 with the right eye's column 3, the left eye's column 3 with the right eye's column 4, and so on. This results in your seeing a ghost set of columns, apparently 'behind' the page. The next diagram explains why the 'ghost' set seems to have this depth:
1
*
/ \
/ \
========2*=====*3========
/ \
/ \
O O
To simplify this, I've reduced the columns to just two. Imagine an overhead view, looking edge down on the paper with the columns on. If I'd drawn you in, we'd see the top of your head. The '=' signs represent the top edge of the paper. Stars 2 and 3 are columns on the paper. The 'O's are your eyes. Now, by diverging your eyes you have convinced your brain that stars 2 and 3 are actually the same star seen from different angles. Your brain follows the line of sight for each star and deduces that the star you are looking at is at position 1 where the lines meet. This is 'behind' the page, and thus, a simple 3D effect is created.
With several columns the same principle applies, and you see a whole set of 3D columns.
This is about to become even more complicated. If you aren't sure you've followed it up to now, make sure you do before continuing.
So far, nothing spectacular has been achieved. All that's been done is to make a set of stars seem farther away than it really is. The stereograms you can buy in the shops are much more sophisticated, creating the illusion of an entire 3D scene. To do this, they need to be able to vary the apparent depth across the picture.
The way to make different depths is to adjust the distance between each column. Behold, three more diagrams:
1 2 3 *
* / \
* / \ / \
/ \ / \ / \
==*===*== ==*=====*== ==*=======*==
Given that these diagrams work the same way as the previous one, you can see that the farther apart the columns are, the 'deeper' the 'ghost' image appears to be.
We have now established the basic principles of the way stereograms work. The next section deals with how these might be applied to create a computer program to create stereograms.
The first problem is of how to create the input image. The input image is a normal 2D picture which the program is going to convert into a 3D stereogram. The solution is very simple - different colours in the input picture can represent different depths in the output stereogram. So, for example, if you had a sixteen colour picture, you could decide that colour index 15 represented the nearest parts of the image and that colour index 0 represented the farthest away parts. You could then draw your picture with this in mind. If you wanted, you could set up the palette in your drawing program so that colour 0 was black, colour 15 white, and the remaining colours the intermediate shades of grey. This would make it easier to draw the input picture but would have no effect on the output picture - stereograms are perceived entirely by varying depths. So, you've drawn your picture. Now comes the hard part...
Your program is going to work on one row of pixels at a time, since the way you see stereograms means that each row of pixels is effectively a stereogram on its own - the rest of the picture doesn't need to be taken into account when creating one row. Effectively, each pixel is treated as we treated one 'star' in the earlier examples. The program gets the pixel's colour, and uses it to work out how far away the 'matching' pixel must be (i.e. the other star) to make it look that depth. (If you're not following this, think back to the star examples. The distance between a pair of stars affects how deep the 'ghost' seems. The same goes for pixels.)
A simple way to calculate this distance is as follows. Choose an arbitrary maximum distance - for example, 100 pixels. Now, subtract the colour index of the pixel whose depth you're finding. So, a colour 15 pixel would have a partner 85 pixels away. This would make it seem nearer than a colour 0 pixel, whose partner would be 100 pixels away.
So the process for each pixel in the row, working left to right, is as follows:
-
Get colour index of pixel.
-
Based on this, work out how far to the left its partner should be.
-
If its partner would be off the left edge of the screen, set this pixel to a random colour.
-
If not, set this pixel so that its colour matches that of its partner.
Notice that step 3 effectively sets up your basic pattern of randomly coloured pixels on the left hand side, as the left-most few pixels are bound to have partners who should be off the screen. If you want to be clever about things, you could map a picture containing your own pattern into this space.
That's it! Just repeat until the whole row is done, and then move down to the next row.
If you were working with an 800 by 600 picture, using colours 0-15 to represent far and near, the following BASIC program should produce the desired effect. The program uses these commands –
- PLOT (X,Y,C) to set pixel (X,Y) to colour C
- POINT(X,Y) to return the colour index value of the pixel at (X,Y)
- RND(15) to return a random value between 0 and 15
Co-ordinates (0,0) are at the top left-hand corner of the screen. The 'maximum distance' (described earlier) is 100.
FOR Y=0 TO 599
FOR X=0 TO 799
COL=POINT(X,Y)
DISTANCE=100-COL
IF X-DISTANCE < 0 THEN PLOT(X,Y,RND(15))
IF X-DISTANCE => 0 THEN PLOT(X,Y,POINT(X-DISTANCE,Y))
NEXT X
NEXT Y
In practice, you'll probably need some kind of scaling function. You're aiming for the final maximum distance and minimum distance to be around about one or two inches in the final display medium, since that's the kind of distance that people can comfortably focus on. (At the height of the stereogram craze, a British Sunday newspaper once proudly included some 'magic eye pictures', but blew them up so large that it was impossible for anyone to diverge their eyes far enough to see them.)
So, the maximum and minimum distance values are very important to get right, and 'right' is different depending on the output resolution. You could also vary the number of colours in the input picture, and thus the range of depths available. More depths will make a better looking stereogram.
Finally, a tip for creating your input pictures - smooth depth changes work much better than huge jumps of depth. Putting a very near object on top of a very far object may well result in a stereogram that is very difficult to 'view'. Also, occasionally you may put in a perfectly good image and get garbage out. That's just bad luck - this isn't an exact science, and some pictures just don't seem to work properly.