LTI-Lib latest version v1.9 - last update 10 Apr 2010

ltiArchitecture.h

00001 /*
00002  * Copyright (C) 1998, 1999, 2000, 2001
00003  * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany
00004  * 
00005  * This file is part of the LTI-Computer Vision Library (LTI-Lib)
00006  *
00007  * The LTI-Lib is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License (LGPL)
00009  * as published by the Free Software Foundation; either version 2.1 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * The LTI-Lib is distributed in the hope that it will be
00013  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
00014  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public 
00018  * License along with the LTI-Lib; see the file LICENSE.  If
00019  * not, write to the Free Software Foundation, Inc., 59 Temple Place -
00020  * Suite 330, Boston, MA 02111-1307, USA.  
00021  */ 
00022 
00023 #ifndef _LTI_ARCHITECTURE
00024 #define _LTI_ARCHITECTURE
00025 
00026 /** 
00027 
00028 \page architecture Architecture
00029 
00030 
00031 The LTI-Lib is easy to use due to the specification of a well-defined
00032 programming interface for all classes.  The preservation of its
00033 consistency is partially achieved through the use of the
00034 PERL-script \c ltiGenerator.  Based on a few rudimentary
00035 data provided by the programmer (like class name and parent class)
00036 this script builds some template files, containing all standard
00037 definitions (see \ref howtonew).  After that, only the functionality
00038 needs to be implemented.  This chapter explains all basic concepts
00039 required to understand the meaning of these classes.
00040 
00041 \section arcFunctor Functors, parameters and states
00042 
00043 Most algorithms require \e parameters, i.e. user defined values that
00044 modify its behavior.  For example, the file name is a parameter of an
00045 image loader class, or the size of a filter kernel is a parameter of a
00046 convolution algorithm.
00047 
00048 All algorithms in the LTI-Lib are encapsulated in so-called \e functor classes.
00049 They always enclose a class called \c parameters, that
00050 can be explicitely declared or just inherited from the parent class.
00051 
00052 This means, when you use the LTI-Lib you do not call some functions or
00053 class methods with lots of confusing arguments, some meaning input
00054 data, others the output data, and additionally a (maybe too long) list
00055 of parameters for the algorithm.  A default \c parameters object is
00056 usually set in the functor class, and the methods to call the
00057 functionality expect only the input data and the output objects where
00058 the results are going to be written.  You can of course change the
00059 used parameters as you wish, in order to fit the functor's
00060 functionality to your own needs.
00061 
00062 Example:
00063 
00064 \code
00065 lti::cannyEdges canny;           // an ltilib object to extract the edges
00066                                  // of a channel
00067 canny.apply(myChannel,myEdges);  // extract the edges from myChannel, 
00068                                  // and leave them in myEdges using a
00069                                  // canny functor.  (default parameters used).
00070 
00071 // now we want to do a similar task, but changing Canny's default parameters
00072 
00073 lti::cannyEdges::parameters cannyParams;  // our parameters object
00074 cannyParams.variance = 5;        // change the variance used
00075 canny.setParameters(cannyParams);// and set the new parameters
00076 canny.apply(myChannel,myEdges);  // now extract the new edges from myChannel, 
00077                                  // and leave them in myEdges again.
00078 \endcode
00079 
00080 The parameters of a functor have to be distinguished from its state, which
00081 consists of all those attributes of the class that are computed 
00082 during the execution the algorithm, but are not directly required by the user.
00083 For the Motion History Images (lti::temporalTemplate) for
00084 example, the last presented image must be kept in order to compute the next
00085 iteration.  This image is not a parameter, but a part of the functor's state.
00086 These concepts are shown following image:
00087 
00088 \image html functor.png 
00089 
00090 \n
00091 
00092 The user can change the behavior of the functor through the
00093 parameters.  The functor can also have a state, that eventually (like
00094 the parameters) can also be saved.
00095 
00096 There are several reasons for an independent lti::functor::parameters
00097 class.  You can create several instances with different value sets and
00098 change at once the functionality of your functor with a simple \c
00099 setParameters().  You can load and save your parameters object in a
00100 file, or can give it to a graphical user interface where the user can
00101 choose between several values.  The parameters-classes can also provide
00102 methods to find special configurations of parameters, or to check if the
00103 given values fulfill several conditions imposed by the algorithms.
00104 The parameters contain values directly specified by the user and they
00105 are never modified by the algorithms themselves.
00106 
00107 An usual question is: why do I need to call the method \c getParameters()
00108 to get the parameters instance? would it not be faster if each functor-class
00109 had its own parameters instance that could be used directly?.
00110 
00111 \image html paramhier.png
00112 
00113 \n
00114 
00115 The answer relies partially on memory management issues.  It would be very
00116 expensive if all classes in the functor hierarchy would have an own instance
00117 of parameters, because all inherited parameter attributes would be present
00118 several times.  With the functor hierarchy shown on the left side of
00119 the previous figure an instance of the functor
00120 lti::optimalThresholding would have two parameter objects: the one of
00121 its own with five attributes (\c precision  and the four attributes of the
00122 parent class) and the parameters-instance of lti::thresholdSegmentation
00123 with its four attributes.  In other words, the four attributes of the parent
00124 class are present twice!
00125 
00126 To avoid this problem, there is only one instance of the parameters in
00127 the lti::functor class.  Each class casts this instance to the proper
00128 parameters type using the overloaded method \c getParameters().
00129 
00130 Another important reason for the use of just one parameters-instance
00131 in the functor class appears when the inherited class calls methods
00132 of the parent classes, the later ones could not see the proper
00133 parameters-instance but only the own one, which could contain other values
00134 than those specified by the user.
00135 
00136 The functionality of a functor is always accessed by the methods
00137 \c apply().  They expect input data, (usually \c const references to
00138 objects like matrices of images), and references to output objects
00139 (references to containers where the result is written).  Other
00140 functor methods (the shortcuts) provide comfortable ways to access specific
00141 functionality.  To load an image file, for example, image loaders
00142 provide the shortcut \c load that expects a file name and the image
00143 where the read image result should be written.  Otherwise, you would require to
00144 create a parameters object, set there the file name, give this
00145 parameters-instance to the functor, and at last call the apply
00146 method:
00147 
00148 \code
00149   // an image
00150   lti::image img;
00151 
00152   // functor to load images in Windows BMP format:
00153   lti::loadBMP loader;
00154 
00155   // parameters for the loader
00156   lti::loadBMP::parameters loaderParam;
00157 
00158   // the file to load
00159   loaderParam.filename = "testimage.bmp";
00160 
00161   // load the image into img
00162   loader.setParameters(loaderParam);
00163   loader.apply(img); // load the image!
00164 \endcode
00165 
00166 It is much easier and comfortable to employ following shortcut:
00167 
00168 \code
00169    // an image
00170   lti::image img;
00171 
00172   // functor to load images with Windows BMP format:
00173   lti::loadBMP loader;
00174 
00175   // load an image
00176   loader.load("testimage.bmp",img);
00177 \endcode
00178 
00179 All functors nevertheless provide an interface based on a
00180 \c parameters -object and \c apply -methods, in order to warrant more complex
00181 applications a uniform way to access the functionality of the functor.
00182 
00183 There exist just one \c getParameters() -method per functor and it returns a
00184 \e constant reference to the parameters-instance, this due to the fact
00185 that the attributes of the parameters instance should not be changed by the 
00186 functor itself.  
00187 
00188 Besides the parameters, a functor may have a state, where it stores
00189 information irrelevant for the user but necessary for later computations.
00190 An example for a functor with separated state and parameters is the
00191 lti::principalComponents (PCA) object.  Here you find a parameter
00192 \c autoDim which indicates that another parameter
00193 \c resultDim  should be detected automatically.  In the \c apply method
00194 the value of \c resultDim stored in the internal parameters-instance remains 
00195 unchanged, to respect the wishes of the users.
00196 The PCA computes a transformation matrix that is part of
00197 the functor's state.  It is used later to linearly transform other vectors.  
00198 This matrix is not something that the user usually gives directly, but after
00199 being computed, it can be saved and loaded together with other parts of the 
00200 functor's state (this is done when you load or save the whole functor).
00201 In general, all functors with a state
00202 relevant for later computations can be saved and loaded, i.e. they overload
00203 the methods \c read and \c write.
00204 
00205 \section arcIo Input and Output in the LTI-lib
00206 
00207 Serializable objects in the LTI-Lib (i.e. objects that can be written
00208 or read from disk) never directly use \c std::fstream objects.  The
00209 main reason is that we need to provide a way to support different file
00210 formats at the same time.  The desired file format is determined
00211 through a so called lti::ioHandler.  At this time there are two
00212 file formats.  A Lisp-like one (lti::lispStreamHandler) writes or reads ASCII 
00213 strings in or from a given stream, where different scopes are delimited with
00214 parenthesis.  A binary format (lti::binaryHandler) produces shorter files 
00215 and is faster to be read or written, but can not be edited by hand.
00216 
00217 A uniform way to load or save LTI-Lib-objects and internal types (\c int ,
00218 \c float , \c double , \c std::string, etc.) is provided through
00219 four global functions that passes them properly to a given lti::ioHandler.
00220 These are:
00221 
00222 \code
00223   bool lti::write(ioHandler& handler, 
00224                   const T& data);
00225 
00226   bool lti::read(ioHandler& handler,
00227                  T& data);
00228 
00229 
00230   bool lti::write(ioHandler& handler, 
00231                   const std::string& name,
00232                   const T& data,
00233                   const bool complete=true);
00234 
00235   bool lti::read(ioHandler& handler, 
00236                  const std::string& name,
00237                  T& data,
00238                  const bool complete=true);
00239 \endcode
00240 
00241 The first two functions write or read the contents of an object of type
00242 \c T  in or from the given \c ioHandler .  The third and fourth methods
00243 write the data together with a name that identifies this object.  To read
00244 the data, the given name must match the one used when the data was saved.
00245 
00246 With a handler of type lti::lispStreamHandler following lines
00247 \code
00248   lti::write(handler,"a",5);
00249   lti::write(handler,"b",9);
00250 \endcode
00251 
00252 produce the following output in the output stream associated with the handler:
00253 \code
00254     (a 5)
00255     (b 9)
00256 \endcode
00257 
00258 The parenthesis around each line can be left out if the fourth parameter of
00259 the functions (\c complete ) is set to \c false .  Note that the default
00260 value for this parameter is \c true.
00261 
00262 The lti::lispStreamHandler can find an object using its name:
00263 \code
00264   int x,y;
00265   lti::read(handler,"a",x);
00266   lti::read(handler,"b",y);
00267 \endcode
00268 
00269 After these lines it applies \c x==5 and \c y==9.  Some 
00270 \c ioHandler  (for example lti::binaryStreamHandler ) require that the
00271 read order for different data matches the one used when writing.  If this is
00272 not true, the read methods will return \c false .  Other \c ioHandler 
00273 (like lti::lispStreamHandler ) search for the data using the given name as
00274 key, so that you can use a different reading order.  Following lines would
00275 also result in  \c x==5 and \c y==9:
00276 
00277 \code
00278   int x,y;
00279   lti::read(handler,"b",y);
00280   lti::read(handler,"a",x);
00281 \endcode
00282 
00283 The \c ioHandler  concept makes it possible to define new file formats
00284 \e without requiring to reimplement all read and write methods of the
00285 LTI-Lib classes.  Due to the fact that the read and write methods use a
00286 relative rigorous syntax, it is also relative simple to parse the files.
00287 
00288 Please note that the variables used in the previous examples could also have
00289 any other type defined in the LTI-Lib.   All numerical standard types
00290 (\c int , \c double, etc.), the Standard Template Library (STL) types 
00291 \c std::vector, \c std::list and \c std::map (if you include the
00292 file "\c ltiSTLIoInterface.h") and the most LTI-Lib functors,
00293 parameters and data structures can be serialized.
00294 
00295 \subsection ioExample Example
00296 
00297 How can I save and load some parameters in my program?
00298 
00299 \code
00300   // ltilib functors and their parameters
00301   lti::csPresegmentation segmentor;
00302   lti::csPresegmentation::parameters segParam;
00303 
00304   lti::orientationFeature orientor;
00305   lti::orientationFeature::parameters orientParam;
00306 
00307   // ... initialize the parameters ...
00308 
00309   // how can we write the parameters in a file named "param.txt"?
00310   lti::lispStreamHandler handler;  // the stream handler
00311   std::ofstream out("param.txt");  // the std::fstream used
00312 
00313   // if the output stream is ok, write the data
00314   if (out) {
00315     // the handler have to write the data using the stream "out":
00316     handler.use(out);
00317     
00318     // write the parameters:
00319     lti::write(handler,"orientParam",orientParam); 
00320     lti::write(handler,"segmentParam",segParam);
00321     lti::write(handler,"anInteger",5);
00322   }
00323 \endcode
00324 
00325 And how can we read the data from "param.txt"?
00326 
00327 \code
00328   std::ifstream in("param.txt");
00329 
00330   if (in) {
00331     int x;
00332 
00333     handler.use(in);
00334     
00335     // read the data
00336     lti::read(handler,"orientParam",orientParam); 
00337     lti::read(handler,"segmentParam",segParam);
00338     lti::read(handler,"anInteger",x);
00339   }
00340 \endcode
00341 
00342 You can find a hierarchical list of many functors in the LTI-Lib in the
00343 section \ref functors.
00344 
00345 \section arcViewdraw Visualization Classes
00346 
00347 Not everything in an image processing or computer vision library can be
00348 considered as functor.  Examples for this are the so called drawing and
00349 visualization objects.
00350 
00351 Drawing objects does not execute one algorithm.  They provide different tools
00352 to draw simple geometric constructs on images or other output media.  To use a
00353 drawing object you need to provide it with your \e canvas, i.e. you need to
00354 specify the image where you want to draw.  This is done with the method
00355 \c use().  After that, you can choose the color you want to use with the
00356 method \c setColor().  All lines, circles or points you draw after this,
00357 will be painted using the given color.
00358 
00359 Following example draws a circle and a line on a color image:
00360 
00361 \code
00362   lti::image img(256,256);  // our canvas
00363 
00364   lti::draw<rgbPixel> drawing;  // drawing tool
00365   
00366   drawing.use(img);                         // where should "drawing" paint on?
00367   drawing.setColor(lti::Blue);                  // Blue color
00368   drawing.circle(lti::point(128,128),20,true)); // filled circle, radius 20
00369   drawing.setColor(lti::Red);                   // Red color
00370   drawing.line(10,10,128,128);                  // A red line
00371 \endcode
00372 
00373 Viewer objects do not modify any data, but provide simple ways to visualize
00374 them.  The presentation of the data persists as long as the viewer object
00375 exists.
00376 
00377 You can show the previously drawn image with following code:
00378 
00379 \code
00380   lti::viewer viewer("This is art");  // our viewer object
00381   viewer.show(canvas);                // show our master piece
00382   getchar();                          // just wait 
00383 \endcode
00384 
00385 Available viewers, drawing objects and other visualization tools in the LTI-Lib
00386 are summarized in the section \ref viewers
00387 
00388 \section arcClassifiers Classifiers
00389 
00390 Other important objects that do not fit into the functor paradigm
00391 are the classifiers.  They provide methods to learn from data, and to use the
00392 learned information to analyze new data.  There are different interfaces
00393 for the supervised and unsupervised classifiers.  Both types can be categorized
00394 into instance classifiers that learn from single vectors (like traditional
00395 neural networks) and sequence classifiers that also considered time aspects
00396 (like Hidden Markov Models).
00397 
00398 In the LTI-Lib all classifiers deliver the results using the same data
00399 structures lti::classifier::outputVector, so that the processing of
00400 their results does not depend on the specific classifier used.
00401 
00402 More information about the classifier classes can be found in the sections
00403 \ref docuClassifiers and \ref classifiers.
00404 
00405 */
00406 
00407 #endif
00408 

Generated on Sat Apr 10 15:25:07 2010 for LTI-Lib by Doxygen 1.6.1