OpenVIDIA : Parallel GPU Computer Vision


Home

Screenshots

Installation
Instructions


Quickstart

Programming
Example


CD Source Code

Download

Papers

Project
sf.net project page

Related Projects

Comparametric Toolkit

Links

Open GL Ref.

GeForce FX Overclocking

GPGPU

SourceForge.net Logo

Page design based on Blosxom (which was used originally before the move to sourceforge).

This page best viewed with Dillo, Lynx, w3m, Mozilla-Firefox, Galeon, Epiphany . . .

   

Programming Example: Fragpipe

This is a brief tutorial on how to use the OpenVIDIA package to make your own GPU based programs.

Included in the package is a program called fragpipe (see fragpipe.cc source file). Fragpipe demonstrates how to use Fragment Shading programs to implement a series of image filters. The image below shows this process, where each filter "F" is a fragment program, producing an output texture (the images around the diagram). Depending on the filter, the Fragment Program could be considered the impulse response for "F" (i.e. the filter kernel). Conceptually, fragpipe implements a pipeline of fragment programs, hence the name.


Loading the filters

Take a look at the main() of the fragpipe.cc file. In it, he following code creates the filter objects:

  filter1 = new GenericFilter(320,240, d->getContext(), d->getProfile(),
                              "FPsamples/FP-ibot-undistort.cg");
  filter2 = new GenericFilter(320,240, d->getContext(), d->getProfile(),
                              "FPsamples/FP-rgb2hsv.cg");
So, filter1 encapsulates the program for radial undistortion, and filter2 is a colourspace conversion. A programmer can change the name of the file loaded to their own fragment program. Currently, however, care must be taken to ensure the parameter names match those used in the current Fragment Programs.

Applying the filters

Once loaded, the filters are applied to incoming images/video in the render_redirect function:

  //cascade the filters
  d->applyFilter(filter1, 0,1);
  d->applyFilter(filter2, 1,2);
The ApplyFilter function applies the filter, and takes the following arguments:
  • first argument: filter object
  • second argument: source buffer
  • third argument: target buffer
The original image is initially in buffer 0. in the above, filter1 places its results in buffer 1, and filter2 then processes buffer 1 and places the result in buffer 2. The buffers can be examined by running the program, and pressing the '1' or '2' key to see buffers 1 or 2 (and so on).

Summing Operations

Additionally, a summation type operation is provided by the MomentFilter object. It is created as:
  momentFilter = new MomentFilter(320,240, d->getContext(), d->getProfile() );
It is applied similar to GenericFilter, but takes a 4th argument, a 4 element floating point array which is used to return the sum of the the four channels (RGBA) of the image.
  d->applySumFilter(momentFilter, 3, 4, result );

Currently, it loads the FP-moment.cg program. This program determines what will be in the RGBA channels at each image location when the summation is taken. For instance, if you wanted to know how many pixels have a green value greater than 0.5, you could edit FP-moment.cg to place a '1' the first channel (red) of the output if the input green channel is greater than 0.5, and put a '0' there if not. Then, after applying ther filter, the result array will have its result[0] to be the number of pixels with green value greater than 0.5.

Additional Notes

Separating your operations into different filters allows you to view their results in real-time, which is useful for debugging. However, each filter stage requires copying the result to the video-memory and then reading it again in the next pass. While this doesn't pass data across the AGP/PCI bus, it does make the GPU spend time writing/reading data instead of number crunching. So once you have a set of filters that works, its best to try and optimize the whole fragment pipe by trying to combine them into a single fragment program.

Try and use the summation filter whenever you're interested in a summation result, since it minimizes the amount of data which needs to be sent across the AGP/PCI bus.

Use wisely placed select(0,0,0,timeout) statements (with appropriate timeouts, to avoid busy waiting) to reduce the CPU load without sacrificing performance.