Overview

This page describes a few of the many of the demo scripts included with the Vision Egg. Click on the images to see a 320x240 12 frame per second QuickTime movie of the output of the Vision Egg. Note that this is very small and slow compared to what you would see running the same demo on your computer, especially in fullscreen mode. These demos and many more are a DownloadAndInstall away.

grating.py

The grating demo is a simple Vision Egg application script to show basic operation. First, the screen is initialized, which opens the OpenGL window. Second, a grating object is created with specified parameters of size, position, spatial frequency, temporal frequency, and orientation. Next, a viewport object is created, which is an intermediary between stimuli and screens. Finally, a presentation object is created, which controls the main loop and realtime behavior of any Vision Egg script.

grating.py screenshot

   1 #!/usr/bin/env python
   2 """Sinusoidal grating calculated in realtime."""
   3 
   4 ############################
   5 #  Import various modules  #
   6 ############################
   7 
   8 import VisionEgg
   9 VisionEgg.start_default_logging(); VisionEgg.watch_exceptions()
  10 
  11 from VisionEgg.Core import *
  12 from VisionEgg.FlowControl import Presentation
  13 from VisionEgg.Gratings import *
  14 
  15 #####################################
  16 #  Initialize OpenGL window/screen  #
  17 #####################################
  18 
  19 screen = get_default_screen()
  20 
  21 ######################################
  22 #  Create sinusoidal grating object  #
  23 ######################################
  24 
  25 stimulus = SinGrating2D(position         = ( screen.size[0]/2.0, screen.size[1]/2.0 ),
  26                         anchor           = 'center',
  27                         size             = ( 300.0 , 300.0 ),
  28                         spatial_freq     = 10.0 / screen.size[0], # units of cycles/pixel
  29                         temporal_freq_hz = 1.0,
  30                         orientation      = 45.0 )
  31 
  32 ###############################################################
  33 #  Create viewport - intermediary between stimuli and screen  #
  34 ###############################################################
  35 
  36 viewport = Viewport( screen=screen, stimuli=[stimulus] )
  37 
  38 ########################################
  39 #  Create presentation object and go!  #
  40 ########################################
  41 
  42 p = Presentation(go_duration=(5.0,'seconds'),viewports=[viewport])
  43 p.go()

target.py

The target demo creates a small target which moves across the screen. The target is spatially anti-aliased by default, meaning that the edges can have colors intermediate between the target and the background to reduce jaggies. This demo also introduces the concept of controllers which allow realtime control of a Vision Egg stimulus through any number of means, including a data acquisition device, a network connection, or software control.

target.py screenshot

   1 #!/usr/bin/env python
   2 """A moving target."""
   3 
   4 ############################
   5 #  Import various modules  #
   6 ############################
   7 
   8 import VisionEgg
   9 VisionEgg.start_default_logging(); VisionEgg.watch_exceptions()
  10 
  11 from VisionEgg.Core import *
  12 from VisionEgg.FlowControl import Presentation, Controller, FunctionController
  13 from VisionEgg.MoreStimuli import *
  14 from math import *
  15 
  16 #################################
  17 #  Initialize the various bits  #
  18 #################################
  19 
  20 # Initialize OpenGL graphics screen.
  21 screen = get_default_screen()
  22 
  23 # Set the background color to white (RGBA).
  24 screen.parameters.bgcolor = (1.0,1.0,1.0,1.0)
  25 
  26 # Create an instance of the Target2D class with appropriate parameters.
  27 target = Target2D(size  = (25.0,10.0),
  28                   color      = (0.0,0.0,0.0,1.0), # Set the target color (RGBA) black
  29                   orientation = -45.0)
  30 
  31 # Create a Viewport instance
  32 viewport = Viewport(screen=screen, stimuli=[target])
  33 
  34 # Create an instance of the Presentation class.  This contains the
  35 # the Vision Egg's runtime control abilities.
  36 p = Presentation(go_duration=(10.0,'seconds'),viewports=[viewport])
  37 
  38 #######################
  39 #  Define controller  #
  40 #######################
  41 
  42 # calculate a few variables we need
  43 mid_x = screen.size[0]/2.0
  44 mid_y = screen.size[1]/2.0
  45 max_vel = min(screen.size[0],screen.size[1]) * 0.4
  46 
  47 # define position as a function of time
  48 def get_target_position(t):
  49     global mid_x, mid_y, max_vel
  50     return ( max_vel*sin(0.1*2.0*pi*t) + mid_x , # x
  51              max_vel*sin(0.1*2.0*pi*t) + mid_y ) # y
  52 
  53 # Create an instance of the Controller class
  54 target_position_controller = FunctionController(during_go_func=get_target_position)
  55 
  56 #############################################################
  57 #  Connect the controllers with the variables they control  #
  58 #############################################################
  59 
  60 p.add_controller(target,'position', target_position_controller )
  61 
  62 #######################
  63 #  Run the stimulus!  #
  64 #######################
  65 
  66 p.go()

targetBackground.py

The targetBackground demo illustrates how easy it is to combine multiple stimuli. A spatially anti-aliased small target is drawn as before, but this occurs over a spinning drum.

This demo also introduces more power of OpenGL -- coordinate transforms that occur in realtime via projections. In the Vision Egg, a projection is a parameter of the viewport. In the default case (such as for the small target), the viewport uses pixel coordinates to create an orthographic projection. This allows specification of stimulus position and size in units of pixels. However, a projection also allows other 3D to 2D projections, such as that used to draw the spinning drum. This drum, which is defined in 3D, is drawn using a perspective projection. Because the drum uses a different projection than the small target, it needs its another viewport to link it to the screen.

targetBackground.py screenshot

   1 #!/usr/bin/env python
   2 """Moving target over a spinning drum."""
   3 
   4 ############################
   5 #  Import various modules  #
   6 ############################
   7 
   8 from VisionEgg import *
   9 start_default_logging(); watch_exceptions()
  10 
  11 from VisionEgg.Core import *
  12 from VisionEgg.FlowControl import Presentation, Controller, FunctionController
  13 from VisionEgg.MoreStimuli import *
  14 from VisionEgg.Textures import *
  15 import os
  16 from math import *
  17 
  18 # Initialize OpenGL graphics screen.
  19 screen = get_default_screen()
  20 
  21 #######################
  22 #  Create the target  #
  23 #######################
  24 
  25 # Create an instance of the Target2D class with appropriate parameters
  26 target = Target2D(size  = (25.0,10.0),
  27                   color      = (1.0,1.0,1.0,1.0), # Set the target color (RGBA) black
  28                   orientation = -45.0)
  29 
  30 # Create a viewport for the target
  31 target_viewport = Viewport(screen=screen, stimuli=[target])
  32 
  33 #####################
  34 #  Create the drum  #
  35 #####################
  36 
  37 # Get a texture
  38 filename = os.path.join(config.VISIONEGG_SYSTEM_DIR,"data","panorama.jpg")
  39 texture = Texture(filename)
  40 
  41 # Create an instance of SpinningDrum class
  42 drum = SpinningDrum(texture=texture,shrink_texture_ok=1)
  43 
  44 # Create a perspective projection for the spinning drum
  45 perspective = SimplePerspectiveProjection(fov_x=90.0)
  46 
  47 # Create a viewport with this projection
  48 drum_viewport = Viewport(screen=screen,
  49                          projection=perspective,
  50                          stimuli=[drum])
  51 
  52 ##################################################
  53 #  Create an instance of the Presentation class  #
  54 ##################################################
  55 
  56 # Add target_viewport last so its stimulus is drawn last. This way the
  57 # target is always drawn after (on top of) the drum and is therefore
  58 # visible.
  59 p = Presentation(go_duration=(10.0,'seconds'),viewports=[drum_viewport,target_viewport])
  60 
  61 ########################
  62 #  Define controllers  #
  63 ########################
  64 
  65 # calculate a few variables we need
  66 mid_x = screen.size[0]/2.0
  67 mid_y = screen.size[1]/2.0
  68 max_vel = min(screen.size[0],screen.size[1]) * 0.4
  69 
  70 # define target position as a function of time
  71 def get_target_position(t):
  72     global mid_x, mid_y, max_vel
  73     return ( max_vel*sin(0.1*2.0*pi*t) + mid_x , # x
  74              max_vel*sin(0.1*2.0*pi*t) + mid_y ) # y
  75 
  76 def get_drum_angle(t):
  77     return 50.0*math.cos(0.2*2*math.pi*t)
  78 
  79 # Create instances of the Controller class
  80 target_position_controller = FunctionController(during_go_func=get_target_position)
  81 drum_angle_controller = FunctionController(during_go_func=get_drum_angle)
  82 
  83 #############################################################
  84 #  Connect the controllers with the variables they control  #
  85 #############################################################
  86 
  87 p.add_controller(target,'position', target_position_controller )
  88 p.add_controller(drum,'angular_position', drum_angle_controller )
  89 
  90 #######################
  91 #  Run the stimulus!  #
  92 #######################
  93 
  94 p.go()

put_pixels.py

The put_pixels demo puts arbitrary array data to the screen. For the sake of simplicity this example uses only solid, uniformly colored arrays. The screen is updated with a new array on every frame, which will reveal tearing artifacts if you do not have buffer swaps synchronized to VSync.

This demo also illustrates an alternative to using the FlowControl module by using pygame's event handling.

   1 #!/usr/bin/env python
   2 import VisionEgg
   3 VisionEgg.start_default_logging(); VisionEgg.watch_exceptions()
   4 
   5 from VisionEgg.Core import *
   6 import pygame
   7 from pygame.locals import *
   8 
   9 screen = get_default_screen()
  10 screen.set( bgcolor = (0.0,0.0,0.0) ) # black (RGB)
  11 
  12 white_data = (Numeric.ones((100,200,3))*255).astype(Numeric.UnsignedInt8)
  13 red_data = white_data.copy()
  14 red_data[:,:,1:] = 0 # zero non-red channels
  15 
  16 blue_data = white_data.copy()
  17 blue_data[:,:,:-1] = 0 # zero non-blue channels
  18 
  19 frame_timer = FrameTimer() # start frame counter/timer
  20 count = 0
  21 quit_now = 0
  22 
  23 # This style of main loop is an alternative to using the
  24 # VisionEgg.FlowControl module.
  25 while not quit_now:
  26     for event in pygame.event.get():
  27         if event.type in (QUIT,KEYDOWN,MOUSEBUTTONDOWN):
  28             quit_now = 1
  29     screen.clear()
  30     count = (count+1) % 3
  31     if count == 0:
  32         pixels = white_data
  33     elif count == 1:
  34         pixels = red_data
  35     elif count == 2:
  36         pixels = blue_data
  37     screen.put_pixels(pixels=pixels,
  38                       position=(screen.size[0]/2.0,screen.size[1]/2.0),
  39                       anchor="center")
  40     swap_buffers() # display what we've drawn
  41     frame_timer.tick() # register frame draw with timer
  42 frame_timer.log_histogram()

Many more demos are included!

Documentation/Tutorial (last edited 2008-01-04 11:10:41 by localhost)