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