Are Autostereograms Useful

for Computer Graphics

and Scientific Visualization?






Jean-François COLONNA
www.lactamme.polytechnique.fr
jean-francois.colonna@polytechnique.edu
CMAP (Centre de Mathématiques APpliquées) UMR CNRS 7641, Ecole Polytechnique, CNRS, 91128 Palaiseau Cedex, France
france telecom, France Telecom R&D

[Site Map, Help and Search [Plan du Site, Aide et Recherche]]
[The Y2K bug [Le bug de l'an 2000]]
[Do you believe that Real Numbers exist for a computer and that floating point computations are safe?]
[Please, visit A Virtual Space-Time Travel Machine, the place where you can find more than 5400 pictures between Art and Science]
(CMAP28 WWW site: this page was created on 04/25/2000 and last updated on 01/28/2014 15:08:16 -CET-)



(published in The Visual Computer, Volume 11, Number 7, 10/1995)


Abstract: Autostereograms are images that can be observed as 'flat' 2D pictures as well as a display of 3D objects without any extra apparatus. More than one million copies of books about this subject have been recently sold: but are autostereograms useful for computer graphics and scientific visualization? This short note provides some assistance for easily designing still and animated autostereograms, and tries to encourage reader involvement in finding new scientific applications.


Keywords: autostereogram, computer graphics, scientific visualization.



Painting, photography or cinematography reproduce our 3D world as 2D pictures. But since these inventions, people have made attempts to simulate the third dimension by means of displaying different pictures to left and right eyes. For example, during the 1900 International Exhibition held in Paris, Auguste and Louis Lumiere made stereoscopic movie projections. Unfortunately almost all techniques used for stereoscopic vision require extra devices (most of them are glasses: color or polarized filters, electronic shutter,... [1]) that must be carried by the viewer. This is probably the reason why that kind of hardware is relatively unsuccessful...

Recently, scientists like Christophe Tyler, Mayren Clarke, Harold Thimbleby, Jacques Ninio [2],... discovered a new way of simulating 3D scenes: the autostereograms; currently, more than one million copies of books showing these new pictures (like [3]) have been sold (most in Japan and in the USA)...

The basic idea is to disguise the 3D object(s) to be displayed by means of a (pseudo-) periodical (along the horizontal axis) texture (see [4] for further information): the periodicity will allow the two eyes to look at equivalent points of the texture (that is points that are distinct and an integer number of periods apart -one is the most appropriate value-). The following C-like program (the full C program is also available) gives one of the possible algorithms (the texture shift formula is derived from one found in [5]); it has been chosen because on the one hand it is very simple to write and understand, and on the other hand it is independent of the texture used and of the 3D objects(s) to be displayed; finally by this way we hope to encourage the reader involvement. Let picture denotes the C-type for a XY-array (each pixel being a char, an int,...). The algorithm given here is for false color textures. For true color textures, it suffices to repeat this algorithm for each RGB component; generally the depth field will be the same, but three different ones can be used...


                    #define   Xmodulo(x,period) MODULO(x,Xmin,period)
                                                            /* put 'x' inside [Xmin,Xmin+period-1].                                                      */
                    picture   Autostereogram;
                                                            /* the autostereogram to be generated.                                                       */
                    picture   Depth;
                                                            /* the depth field of the scene to be displayed is defined itself                            */
                                                            /* as a picture ; high values correspond to points that are close                            */
                                                            /* to the viewer. It could be, for example, the contain of a                                 */
                                                            /* Z-Buffer obtained after a 3D synthesis ; but it could be                                  */
                                                            /* anything you like : a grey level picture,... The door is                                  */
                                                            /* wide open for artistic creation.                                                          */
                    unsigned  int IntrinsicPeriod;
                    unsigned  int ActualPeriod;
                    picture   Texture;
                                                            /* the 2D texture to be used. Two periods are characteristic :                               */
                                                            /*                                                                                           */
                                                            /* IntrinsicPeriod gives the intrinsic period of Texture ; for                               */
                                                            /* example, if Autostereogram should be made of 5 vertical                                   */
                                                            /* bands (see Figure 2), it is equal to (Xmax-Xmin+1)/5.                                     */
                                                            /*                                                                                           */
                                                            /* ActualPeriod generally equals IntrinsicPeriod but it could                                */
                                                            /* be different in the case where texture is pseudo-periodical.                              */
                                                            /* It gives the width of the used area of Texture.                                           */
                    picture   TemporaryTexture;
                                                            /* a temporary picture containing the texture during the                                     */
                                                            /* process of circular shifting of Texture.                                                  */
                    int       TextureSwap;
                                                            /* a logical indicator ; a null value allows the possible swap                               */
                                                            /* of texture points during the left shift process. This allows                              */
                                                            /* "dynamical" effects and for example "ghost" subsets of the                                */
                                                            /* 3D object that appear and disappear according to the point                                */
                                                            /* of view.                                                                                  */
                    int       X,Y;
                    for       (Y=Ymin ; Y<=Ymax ; Y++)
                              {
                              for       (X=Xmin ; X<=Xmax ; X++)
                                        {
                                        TemporaryTexture[X][Y]=Texture[X][Y];
                                                            /* copy the whole input texture (could be optimized according                                */
                                                            /* to IntrinsicPeriod and ActualPeriod).                                                     */
                                        }
                              }
                    for       (Y=Ymin ; Y<=Ymax ; Y++)
                              {
                              int       FormerLeftshift=0;
                              for       (X=Xmin ; X<=Xmax ; X++)
                                        {
                                        int       Leftshift=StrictlyPositiveMultiplicativeFactor*Depth[X][Y];
                                        int       ActualLeftshift=((TextureSwap==0) || ((FormerLeftshift-Leftshift) <= 1)) ? Leftshift : FormerLeftshift-1;
                                                            /* Texture will be left circular shifted proportionally to the                               */
                                                            /* current Depth ; however, the actual left shift depends on                                 */
                                                            /* the swapping enabling of the texture.                                                     */
                                        int       n;
                                        for       (n=1 ; n<=(ActualPeriod/IntrinsicPeriod) ; n++)
                                                            /* for the sake of simplicity it is assumed that IntrinsicPeriod                             */
                                                            /* divides exactly ActualPeriod.                                                             */
                                                  {
                                                  int       Xperiodic=Xmodulo(X+(n-1)*IntrinsicPeriod,ActualPeriod);
                                                  TemporaryTexture[Xmodulo(Xperiodic,ActualPeriod)][Y]=TemporaryTexture[Xmodulo(Xperiodic+ActualLeftshift,ActualPeriod)][Y];
                                                            /* shift the current texture according to the current depth.                                 */
                                                  }
                                        Autostereogram[X][Y]=TemporaryTexture[Xmodulo(X,ActualPeriod)][Y];
                                                            /* generation of Autostereogram.                                                             */
                                        FormerLeftshift=ActualLeftshift;
                                        }
                              }

Figure 2 displays a five-band autostereogram computed with the preceding algorithm. The texture used was generated starting with a random picture (picture[X][Y]=random()); then this picture was Fourier-filtered. Both intrinsic and actual periods were equal to 1/5th of the width of the autostereogram to be generated. The depth field was obtained by keeping the Z-Buffer during Figure 1 synthesis.

For the "beginners" it is suggested to hold the autostereogram right to the nose and very slowly to pull it away from the face. The viewer must look through the picture and try not to blink the eyes. When using a computer screen for viewing an autostereogram, it is suggested to display it inside a bigger black window.

It is noteworthy that the 3D effect seems to be the same (in particular as "strong") whatever the texture (for example the texture band can be strictly random...) and the colors used; by the way, a very beautiful magic (and simple) effect for a false color autostereogram is to rotate the color table: one can see the colors glide over the surface of the 3D object(s). Moreover, when using textures that are periodical along two orthogonal axes, it is possible to mutiplex two different tridimensional objects within the same picture; a first autostereogram is computed with the first object and is then used itself as a texture for the second object after an appropriate p/2 rotation. However, this process requires slight object depths in order to shift the texture as little as possible. Finally, when giving a null value to the TextureSwap indicator, ghost objects can appear and disappear according to the point of view (see Figure 3).

It is then very easy to produce animations. It suffices to chose a texture (it is suggested that it remains the same during the whole sequence, but it could be time dependent: the process still works!) and to have a time dependent depth field. Figure 4 displays sixteen frames from an autostereogram animation computed during a journey along the quaternionic Mandelbrot set border [6]. To watch such a video sequence, the viewer must take its time for the first image of the sequence, and then play the animation.

Unfortunately for still autostereograms, the 3D view displays only the shape of the object and not their colors and textures; this default could limit the usefulness of autostereograms. For animated autostereograms the situation is worse: as a matter of fact, the disguise texture is shifted according to the current depth; in an animation the depth field changes from frame to frame. The disguise texture will then incessantly wave during the animation; this artifact could be inacceptable (even if this process works!).

A solution to these problems is to chose, for each animation frame, a picture of the object(s) to be displayed as the texture; for example Figure 1 was used to compute the autostereogram of Figure 5. In this case to have the widest view on the object(s) one must chose the smallest number of vertical bands (that is three). To be input in the preceding algorithm (as Depth as well as Texture), the "realistic" view (see again Figure 1) as to be shifted in the following way:


                    picture   DepthOfRealisticView
                    picture   RealisticView;
                                                           /* the "realistic" view of the object(s) to be displayed.                                     */
                    picture   Depth;
                    picture   Texture;
                                                           /* depth field and 2D texture to be used to produce the autostereogram.                       */
                    int       X,Y;
                    for       (Y=Ymin ; Y<=Ymax ; Y++)
                              {
                              for       (X=Xmin ; X<=Xmax ; X++)
                                        {
                                        Depth[X][Y]= ((X>=(Xmin+((Xmax-Xmin)/3))) && (X<(Xmin+((2*(Xmax-Xmin))/3)))) ? DepthOfRealisticView[X][Y] : 0;
                                                           /* the depth field is extracted from the center of the realistic                              */
                                                           /* view and remains center aligned. The left and right bands                                  */
                                                           /* are initialized to zero thus giving birth to a background                                  */
                                                           /* plane.                                                                                     */
                                        Texture[X][Y]=(X<(Xmin+((Xmax-Xmin)/3))) ? RealisticView[X+((Xmax-Xmin)/3)][Y] : 0;
                                                           /* the 2D texture is extracted from the center of the realistic                               */
                                                           /* view and is left aligned.                                                                  */
                                        }
                              }

The autostereogram algorithm is then used with both actual and intrinsic periods equal to one third the width of the "realistic" autostereograms to be generated. The obtained autostereograms (see Figure 5 for the still one and the Figure 6 for the animated one) display one third of the object with their colors and textures (by the way this process works for false and true colors pictures as well...).

However, from a scientific point of view, which one of the previously displayed pictures is the most useful: Figure 1, or ? The previously described program has already been used to produce scientific visualizations within numerous scientific fields (fractal geometry as illustrated in this paper, bidimensional turbulence, study of surface vibrations,...). From these first experiments, it appears that an appropriate tridimensional visualization is at least as useful as an autostereogram; moreover, it is noteworthy that about 5% of the population is "blind" to this stereo effect.

In this short note, we have shown that ("realistic" or not) autostereograms can be computed and animated very easily and very fast starting from pre-computed data (depth field and texture). One of their great advantages is that the 3D effect produced works whatever the underlying "hardware" used to display them: color prints, black and white hardcopies, slides, video monitors, video projections,... We hope to encourage the reader involvement then giving birth to new scientific applications for the autostereograms.










Copyright (c) Jean-François Colonna, 2000-2014.
Copyright (c) France Telecom R&D and CMAP (Centre de Mathématiques APpliquées) UMR CNRS 7641 / Ecole Polytechnique, 2000-2014.