last update 20 Sep 2009 |
00001 /* 00002 * Copyright (C) 1998 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 00042 /** 00043 * \file cvrLabelAdjacencyMap.h 00044 * \author Pablo Alvarado 00045 * \date 18.11.2002 00046 * 00047 * $Id: cvrLabelAdjacencyMap.h,v 1.8 2006/05/12 15:09:55 doerfler Exp $ 00048 */ 00049 00050 #ifndef _CVR_LABEL_ADJACENCY_MAP_H_ 00051 #define _CVR_LABEL_ADJACENCY_MAP_H_ 00052 00053 #include "cvrFunctor.h" 00054 #include "cvrImage.h" 00055 #include <map> 00056 00057 namespace cvr { 00058 00059 /** 00060 * Visualize a label mask in a color image 00061 * 00062 * This class draws a color image using as input a labeled mask. The 00063 * colors used for each label are chosen based on the adjacency, so that 00064 * two neighbor labels never get the same color. 00065 * 00066 * You can choose the kind of neighborhood used (4 or 8 neighborhood) and 00067 * the number of colors you want to use. 00068 * 00069 * Other classes, like the viewers, may require partial computations, like 00070 * the adjacency graph, which is a kind of 00071 * 00072 * @ingroup gVisualization 00073 */ 00074 class labelAdjacencyMap : public functor { 00075 00076 public: 00077 00078 /** 00079 * Default color palette 00080 * 00081 * {cvr::Black, cvr::Red, cvr::Green, cvr::Blue, 00082 * cvr::Yellow, cvr::Cyan, cvr::Magenta, cvr::DarkOrange, 00083 * cvr::Lemon, cvr::Violet} 00084 */ 00085 static const palette defaultPalette; 00086 00087 /** 00088 * The parameters for the class labelAdjacencyMap 00089 */ 00090 class parameters : public functor::parameters { 00091 00092 public: 00093 00094 /** 00095 * default constructor 00096 */ 00097 parameters(); 00098 00099 /** 00100 * copy constructor 00101 * @param other the parameters object to be copied 00102 */ 00103 parameters(const parameters& other); 00104 00105 /** 00106 * destructor 00107 */ 00108 ~parameters(); 00109 00110 /** 00111 * returns name of this type 00112 */ 00113 virtual const std::string& name() const; 00114 00115 /** 00116 * copy the contents of a parameters object 00117 * @param other the parameters object to be copied 00118 * @return a reference to this parameters object 00119 */ 00120 parameters& copy(const parameters& other); 00121 00122 /** 00123 * copy the contents of a parameters object 00124 * @param other the parameters object to be copied 00125 * @return a reference to this parameters object 00126 */ 00127 parameters& operator=(const parameters& other); 00128 00129 /** 00130 * returns a pointer to a clone of the parameters 00131 */ 00132 virtual parameters* clone() const; 00133 00134 /** 00135 * returns a pointer to a new instance of the parameters 00136 */ 00137 virtual parameters* newInstance() const; 00138 00139 /** 00140 * write the parameters in the given ioHandler 00141 * @param handler the ioHandler to be used 00142 * @param complete if true (the default) the enclosing begin/end will 00143 * be also written, otherwise only the data block will be written. 00144 * @return true if write was successful 00145 */ 00146 virtual bool write(ioHandler& handler,const bool complete=true) const; 00147 00148 /** 00149 * read the parameters from the given ioHandler 00150 * @param handler the ioHandler to be used 00151 * @param complete if true (the default) the enclosing begin/end will 00152 * be also written, otherwise only the data block will be written. 00153 * @return true if write was successful 00154 */ 00155 virtual bool read(ioHandler& handler,const bool complete=true); 00156 00157 // ------------------------------------------------ 00158 // the parameters 00159 // ------------------------------------------------ 00160 00161 /** 00162 * If true, the mininum number of colors will be used, which will depend 00163 * on the neighborhood used. (a max of 4 colors is required for a 00164 * 4 neighborhood, and a max of 8 color for a 8 neighborhood). 00165 * 00166 * If false, all colors in the palette might be used. 00167 * 00168 * Default: false 00169 */ 00170 bool minColors; 00171 00172 /** 00173 * The colors used to denote the labels. Note that the assigment is not 00174 * 1 to 1, but will be done depending on the adjacency of the labels. 00175 * 00176 * Default: {cvr::Black,cvr::Red,cvr::Green,cvr::Blue,cvr::Yellow, 00177 * cvr::Cyan,cvr::Magenta,cvr::DarkOrange,cvr::Lemon, 00178 * cvr::Violet} 00179 * 00180 * This default palette can be accessed anytime as 00181 * cvr::labelAdjacencyMap::defaultPalette 00182 */ 00183 palette thePalette; 00184 00185 /** 00186 * Neighborhood used. 00187 * 00188 * Valid values are 4 and 8. Other values will be considered as 00189 * 8-neighborhood. 00190 * 00191 * Default value: 8 00192 */ 00193 int neighborhood; 00194 00195 }; 00196 00197 00198 /** 00199 * This auxiliary class stores a simple adjacency graph between labels, in 00200 * which only the edges between the nodes contain data. 00201 * 00202 * It uses std::map to store in a memory friendly way a sparse 00203 * "adjacency" matrix. 00204 * 00205 * In principle, only the "neighbors_" attribute of the class could also be 00206 * used as "graph" representation, but this class allows for some common 00207 * tasks with that container structure. 00208 */ 00209 class graph { 00210 friend class labelAdjacencyMap; 00211 public: 00212 /** 00213 * Construct an empty graph 00214 */ 00215 graph(); 00216 00217 /** 00218 * Increment the value stored in the edge between the nodes identified by 00219 * row and col. If you visualize the graph as a matrix, this increments 00220 * the element at (row,col). 00221 */ 00222 void acc(const int row,const int col); 00223 00224 /** 00225 * Remove all data of graph 00226 */ 00227 void clear(); 00228 00229 /** 00230 * Find the largest row id used 00231 */ 00232 int findMaxId() const; 00233 00234 /** 00235 * Find the largest row id used 00236 */ 00237 int findMinId() const; 00238 00239 /** 00240 * Find the largest row id used 00241 */ 00242 void findMinMaxIds(int& minRow,int& maxRow) const; 00243 00244 /** 00245 * Each node in nodes_ has a "list" of ids of the neighbors of that node. 00246 * There exist therefore an edge for each element in a list of this type. 00247 */ 00248 typedef std::map<int,int> edges_type; 00249 00250 /** 00251 * Double hash for the neighbors 00252 */ 00253 typedef std::map<int, edges_type > nodes_type; 00254 00255 private: 00256 /** 00257 * The neighbors is a sort of list of lists of neighbors for each 00258 * label. 00259 * 00260 * The key of the hash is a label/region id, and the data is a 00261 * hash of the neighbors, also keyed by the region/label id and 00262 * as data the graph usually will contain the number of elements 00263 * in common, i.e. the number of times acc() was called. 00264 */ 00265 nodes_type nodes_; 00266 }; 00267 00268 00269 /** 00270 * default constructor 00271 */ 00272 labelAdjacencyMap(); 00273 00274 /** 00275 * Construct a functor using the given parameters 00276 */ 00277 labelAdjacencyMap(const parameters& par); 00278 00279 /** 00280 * copy constructor 00281 * @param other the object to be copied 00282 */ 00283 labelAdjacencyMap(const labelAdjacencyMap& other); 00284 00285 /** 00286 * destructor 00287 */ 00288 virtual ~labelAdjacencyMap(); 00289 00290 /** 00291 * returns the name of this type ("labelAdjacencyMap") 00292 */ 00293 virtual const std::string& name() const; 00294 00295 /** 00296 * Compute the adjacency map of the given 8-bit labeled mask. 00297 * 00298 * @param src channel8 with the source data. 00299 * @param dest image where the result will be left. 00300 * @return true if apply successful or false otherwise. 00301 */ 00302 bool apply(const matrix<ubyte>& src,image& dest) const; 00303 00304 /** 00305 * Compute the adjacency map of the given 32-bit labeled mask. 00306 * 00307 * The input data cannot have label ids less than zero and 00308 * internally a look-up table of the size equal to the maximum 00309 * value in the input data plus one will be created. So, it will 00310 * be assumed that the input mask has all its labels with low positive ids. 00311 * 00312 * @param src matrix<int> with the source data. 00313 * @param dest image where the result will be left. 00314 * @return true if apply successful or false otherwise. 00315 */ 00316 bool apply(const matrix<int>& src,image& dest) const; 00317 00318 /** 00319 * copy data of "other" functor. 00320 * @param other the functor to be copied 00321 * @return a reference to this functor object 00322 */ 00323 labelAdjacencyMap& copy(const labelAdjacencyMap& other); 00324 00325 /** 00326 * alias for copy member 00327 * @param other the functor to be copied 00328 * @return a reference to this functor object 00329 */ 00330 labelAdjacencyMap& operator=(const labelAdjacencyMap& other); 00331 00332 /** 00333 * returns a pointer to a clone of this functor. 00334 */ 00335 virtual labelAdjacencyMap* clone() const; 00336 00337 /** 00338 * returns a pointer to a new instance of this functor. 00339 */ 00340 virtual labelAdjacencyMap* newInstance() const; 00341 00342 /** 00343 * returns used parameters 00344 */ 00345 const parameters& getParameters() const; 00346 00347 /** 00348 * Compute the adjacency graph of labels for the given labeled mask. 00349 */ 00350 bool adjacency(const matrix<ubyte>& mask,graph& dest) const; 00351 00352 /** 00353 * Compute the adjacency graph of labels for the given labeled mask. 00354 */ 00355 bool adjacency(const matrix<int>& mask,graph& dest) const; 00356 00357 /** 00358 * Compute a transformation Look-up Table that maps the id of a label to 00359 * the corresponding entry in the parameters palette. 00360 */ 00361 bool computePalette(const graph& adj,palette& pal) const; 00362 00363 00364 /** 00365 * Compute a transformation Look-up Table that maps the id of a label to 00366 * the corresponding entry in the parameters palette. 00367 */ 00368 bool computePalette(const graph& adj,ivector& pal) const; 00369 00370 protected: 00371 00372 /** 00373 * Compute a "palette" from the graph, which can be accessed with the 00374 * id of a label to get the corresponding color in the map. 00375 * 00376 * The minimum number of colors will be used. 00377 */ 00378 bool computeMinPalette(const graph& adj,palette& pal) const; 00379 00380 00381 /** 00382 * Compute a transformation Look-up Table that maps the id of a label to 00383 * the corresponding entry in the parameters palette. 00384 * 00385 * The minimum number of colors will be used. 00386 */ 00387 bool computeMinPalette(const graph& adj,ivector& pal) const; 00388 00389 /** 00390 * Compute a "palette" from the graph, which can be accessed with the 00391 * id of a label to get the corresponding color in the map. 00392 * 00393 * The maximum number of colors will be used. 00394 */ 00395 bool computeMaxPalette(const graph& adj,palette& pal) const; 00396 00397 /** 00398 * Compute a transformation Look-up Table that maps the id of a label to 00399 * the corresponding entry in the parameters palette. 00400 * 00401 * The maximum number of colors will be used. 00402 */ 00403 bool computeMaxPalette(const graph& adj,ivector& pal) const; 00404 00405 }; 00406 } 00407 00408 #endif 00409