[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1. Introduction

Chapter summary: VXL is efficient, simple, and fun to use.

This document describes vxl, a collection of C++ libraries designed for computer vision research. Because it's for computer vision it needs to be efficient, handling large quantities of numerical data with little overhead. Because it's for research it must be portable, so that one can write and run one's program on any machine available, for example in order to access a special camera or fast image processing hardware.

The vxl collection's portability and efficiency are traits which are due in large part to its parentage. The package was built by extracting the core functionalities of two large systems: the "Image Understanding Environment" (IUE) and "Target junior" (TargetJr). Although these environments contain a wealth of useful code, and have facilitated much research, they are widely known for their bulk, and the difficulty of learning to use them. Common complaints have been

Despite these complaints, the quality of the software available in the environments, and the promise of a sustained, concerted software development effort has meant that the IUE/TargetJr has many users worldwide. The job of vxl is to make that many happy users, by creating a set of libraries which have the same useful code, but which are light, fast, and not weird.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.1 Core Libraries

The core of vxl was defined in February 2000, and comprises six libraries plus a compatibility layer.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.1.1 vcl: The C++ compatibility layer.

The job of vcl is to turn your compiler into a standard C++ compiler. In particular, it ensures that your standard library behaves at least something like that defined in the ANSI/ISO standard. In an ideal world, vcl would not be necessary, as all compiler vendors would ship perfectly compliant systems. But then, in a perfect world, C++ wouldn't be the only choice for high efficiency high-level programming.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.1.2 vbl: Basic Templates.

The basic templates library contains a small set of generally useful templated containers and algorithms, e.g. smart pointers, triples, and sparse_arrays. Many of these things should have been in the STL.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.1.3 vul: Utilities.

This contains a number of generally useful C++ classes and functions, notably file and directory handling, command-line argument parser, string utilities, a timer, etc.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.1.4 vnl: Numerical algorithms.

The main classes in vnl are the matrix and vector classes, which are very simple c-like objects. There is no reference counting, objects are returned by value, or passed into routines. The use of objects to hold the output of matrix decompositions also reduces the amount of copying that needs to be done. The numerical algorithms are wrappers around public-domain, high quality Fortran code from the TargetJr netlib library but that part of vnl is placed in a separate library: vnl_algo.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.1.5 vil: Imaging.

The imaging library is designed to work well with very large images, but its primary design objective is to be fast and convenient for the typical in-core images that are encountered in video and digital image processing. A panoply of file formats is handled, and it is easy to add support for a new format.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.1.6 vgl: Geometry.

It is in geometry that the spartan aesthetic of the core of vxl becomes most apparent. The library deals with the geometry of points, curves, and other objects in 2 or more dimensions, but may not call on the numerics library. Therefore, it is restricted to operations which it is reasonable to express in standard C++, which places a useful limit on what may be placed there. For example, surface fitting cannot be in geometry as it would require the singular value decomposition. However, there is much here that is useful, and the library is quite large enough already. The vgl_algo library contains the higher-level code, which is allowed to depend on vnl (and if necessary even on vul).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.1.7 vsl: Binary I/O

This section describes how to save and restore objects using a binary stream. It details how to add the appropriate functions to each class to make use of this facility.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.2 Additional Libraries


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.2.1 vcsl: Co-ordinate Systems

This library allows you to represent and manipulate transformations, transformation graphs, and units of measurement.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.2.2 vpgl: Cameras and Fundamental Matrix

Representation of various types of cameras and geometric relationships between cameras. Provides algorithms for camera calibration and other photogrammetry procedures.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.2.3 vpdl: Probability Distributions

Data structures to represent univariate and multivariate probability distributions and algorithms to operate on them, like sampling and estimation.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.2.4 vidl: Video

Load and save images from video files and sources.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.3 Documentation

The vxl documentation comes in two main forms: this book, and structured comments in the source code, which are automatically extracted. The book is intended to be a single reference, where all the high-level documentation resides. In TargetJr and the IUE there was always a problem finding documentation, as it was in too many places. In vxl, we are following the practice of some other successful systems such as vtk, and providing one monolithic document with, we hope, a good index.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.3.1 The VXL Book

The book (in subdirectory vxl/doc/book) is a human-written collection of VXL documentation, suitable for printing. It is intended to be readable as an introduction to the various facilities provided by the vxl libraries, and to be browsable as a first source of examples and tips.

Why texinfo?

It is written in texinfo, a limited form of LaTeX which allows us to make various forms of output: printed, HTML, windows help files, emacs info, and plain text files. Each of these forms has its adherents, and each is useful. There are other documentation systems which allow multiple output formats, but none match texinfo in the three main formats: paper, hypertext, and ASCII. This is because it's difficult to target such disparate formats, and texinfo has evolved over many years to do it well.

On the other hand, texinfo is maybe hard to learn for those who don't know TeX or LaTeX, so we are keeping an eye on formats such as DocBook.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.3.2 Automatically generated documentation

Although the human-written vxl book is the first source, the definitive authority on what a class or function does must be the source code comments. The book will give a high-level description of the most important and commonly-used features of a class, but the source code contains the details. In order to make these details easier to scan, the vxl source files contain specially structured comments, which can be scanned by the Doxygen program and converted into an attractive hyperlinked reference.

An example of what the syntax for documentation looks like can be found in vxl/doc/vxl_doc_rules.[h,cxx], but briefly a comment line which begins with //: is documentation for the type, function, or variable which follows it. For example

 
//: Brief description of my_class
class my_class {
  //: \brief Brief description, the long one is in the .cxx file
  my_class();
};


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.4 The Design and Evolution of vxl

Design goals:


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.4.1 Motivation

In OpenGL, you guess the name of something, and you're generally right. This is what we would like to achieve with vxl.

Simple and free of programming dogma. For example, many vxl routines exist as C-like functions. For some tasks, C-like functions are more appropriate than a forced object-orientation, for others objects are clearly the more intuitive and compact representation. This is clearly seen in the imaging library, where the vil_image object is passed to and returned from C-like functions, for example

 
  vil_image i = vil_load(filename);
  i = vil_smooth_gaussian(i, 0.6);
  vil_save(i, out_filename, "pnm");

In this case, object orientation ensures that memory is managed efficiently, without unnecessary copying of data, while using functions makes the code more readable.

When building a large system, it is crucial to maintain consistent conventions for file-system structure, and identifier naming. However, a crucial philosophy in the design of vxl is that system conventions must be pragmatic. If programmers are ultimately constrained rather than helped by their environment, they will break the rules, and when they do so, they will break them in inconsistent ways. Therefore it is crucial that consistency within the environment is achieved by conventions that are easy to live with. One example, discussed below, is in the rule governing the relationship between header file names and the objects defined within that header. The general principle, then, is "as close to consistent as comfortable, but no more".


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.4.2 Names

Names are always the biggest issue in programming environments. Uniform naming is one of the most important aspects of a library, and part of the design effort in vxl lays in choosing a good, workable scheme for the naming of classes, functions and files. On the other hand, few issues cause as much debate as the choice of naming conventions. However, we are lucky for two reasons: first, because we wish to run cross-platform, many options are restricted; second, as we can never please everybody, we can just choose a convention and pretend we all hate it.

First things first. The name vxl itself refers to a collection of libraries where the x is replaced by a one or two-letter code describing the contents.

Second, do we use MixedCaseIdentifiers or lowercase_with_underscores? Well, a certain operating system #defines 1300 of the MixedCaseIdentifiers in a header file. Therefore, programs which use names like LoadImage may or may not link. For this reason, we chose the other ugly solution.

For related reasons, source files in vxl all end in .cxx. Template definitions, which look like source files but are essentially header files (or actually #include files, as they are not separately compiled), are suffixed .txx.

Each class or function in a vxl library begins with the name of that library, followed by an underscore, for example vnl_matrix. This makes it easy to locate the source code for any class, and easy to see the list of libraries on which one's program depends.

This scheme was chosen over namespaces because few compilers support namespaces well, and their implications in large-scale development are as yet poorly understood.

An obvious extension of this convention would be to insist that every class or function (in fact, every globally visible symbol exported by a library), should be defined in its own include file, yielding an easy relationship between symbols and include statements. However, such a scheme imposes great demands on programmers, who must generate long lists of includes, and on library writers who must create many files with very little in each. Pragmatism must rule if we are to avoid programmer discomfort, thus chaos. A rule that is still useful, and easier to adhere to is used:

The file vxl/vxl_stuff.h exports only identifiers which begin with vxl_stuff_, and possibly vxl_stuff itself.

An example of a header file which obeys this rule is shown in Figure 1.1.

 
#ifndef vxl_stuff_h_
#define vxl_stuff_h_

enum vxl_stuff_things {
  vxl_stuff_bare,
  vxl_stuff_spartan
};

class vxl_stuff {
};

bool vxl_stuff_grok(vxl_stuff);
extern int vxl_stuff_val;

#endif
Figure 1.1:

Example of a header file vxl_stuff.h which obeys the naming convention. Only identifiers that begin with vxl_stuff_ may be defined.

Of course, this rule is less helpful to clients of the library, who might remember that there is a class called vtl_thing_doer, but not know which header file to include. However, the disadvantage is not great, as the likely options are just vtl/vtl_thing.h and vtl/vtl_thing_doer.h. What is ultimately helpful to clients is a uniform naming scheme, kept so by pragmatic constraints on the library developers.

FAQ: What about operator+(vcl_stuff, vcl_stuff)? Frequently given half-answer: Koenig lookup means it's OK.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1.4.3 Layering

Which brings us on to layering: core vxl libraries may not depend on each other. The numerics library cannot use the handy string manipulation in vul, the imaging library cannot use matrices, or smart pointers. This restriction is central to the design of vxl, because it intrinsically limits the size of the core libraries. It appears to contradict traditional software development practice because it implies that code will be duplicated rather than reused. However, the amount of code duplicated is small, and the benefit of lego libraries is enormous. The current status is encapsulated in this figure

 
Level:   0         1         2          3
         vcl       vbl       vnl_algo   v**l
                   vnl       vil_algo
                   vil       vgl_algo
                   vgl       v*l_io
                   vul
                   vsl

Library layers: libraries in one layer may not call their siblings, even if this means code copying.

However, other alternatives have been considered, and may yet be considered. For example, what about putting vul at level 0.5, so that common utilities can be available to level 1? The problem of course is that everything will end up in the level 0.5 library. We could impose the rule that nothing goes in vul unless it is used in at least two level 1 libraries. I don't know whether that would help or not...

There have been two significant propositions to accept a level 0.5 library - for smart pointers, and binary IO. In both cases it turned out to be relatively straight forward to provide the required functionality without the 0.5 library, and indeed the proposers have found the alternative implementations superior in many ways.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated on May, 1 2013 using texi2html 1.76.