last update 20 Sep 2009 |
00001 /* 00002 * Copyright (C) 1998-2005 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 cvrChannel.h 00044 * Contains the data structure to represent gray valued images 00045 * with one float per pixel. 00046 * \author Pablo Alvarado 00047 * \date 09.04.1999 00048 * 00049 * $Id: cvrChannel.h,v 1.9 2007/04/05 22:55:43 alvarado Exp $ 00050 */ 00051 00052 #ifndef _CVR_CHANNEL_H_ 00053 #define _CVR_CHANNEL_H_ 00054 00055 #include "cvrMatrix.h" 00056 #include "cvrTypes.h" 00057 00058 namespace cvr { 00059 class channel8; 00060 class image; 00061 00062 /** 00063 * A format for float channels. 00064 * 00065 * This class is identical to a matrix of floats except for the method 00066 * castFrom(channel8). 00067 * 00068 * The typical value range is between 0.0f and 1.0f (see cvr::image for more 00069 * information). 00070 * 00071 * @see cvr::image, cvr::channel8 00072 * 00073 * @ingroup gAggregate 00074 * @ingroup gImageProcessing 00075 */ 00076 class channel : public matrix<float> { 00077 public: 00078 00079 /** 00080 * Default constructor creates an empty channel 00081 */ 00082 channel(); 00083 00084 /** 00085 * Create a connected \c rows x \c cols channel and leave the data 00086 * uninitialized. 00087 * 00088 * @param rows number of rows of the channel 00089 * @param cols number of columns of the channel 00090 */ 00091 channel(const int rows,const int cols); 00092 00093 /** 00094 * Create a connected \c size.y x \c size.x channel and initializes 00095 * all elements with \a iniValue 00096 * 00097 * @param size cvr::ipoint with the size of the channel 00098 * (size.x is the number of columns and 00099 * size.y the number of rows) 00100 */ 00101 channel(const ipoint& size); 00102 00103 /** 00104 * Create a connected \c rows x \c cols channel 00105 * and initializes all elements with \a iniValue 00106 * 00107 * @param rows number of rows of the channel 00108 * @param cols number of columns of the channel 00109 * @param iniValue all elements will be initialized with this value 00110 */ 00111 channel(const int rows,const int cols,const float& iniValue); 00112 00113 /** 00114 * Create a connected \c size.y x \c size.x channel and initializes 00115 * all elements with \a iniValue 00116 * 00117 * @param size cvr::ipoint with the size of the channel 00118 * (size.x is the number of columns and 00119 * size.y the number of rows) 00120 * @param iniValue all elements will be initialized with this value 00121 */ 00122 channel(const ipoint& size,const float& iniValue); 00123 00124 /** 00125 * Create a connected \c rows x \c cols channel and initializes all 00126 * elements with the data ipointed by \a data. The first 00127 * \a cols-elements of the data will be copied on the first row, 00128 * the next ones on the second row and so on. 00129 * 00130 * @param rows number of rows of the channel 00131 * @param cols number of columns of the channel 00132 * @param data pointer to the memory block with the data to be initialized 00133 * with. 00134 */ 00135 channel(const int rows,const int cols,const float data[]); 00136 00137 /** 00138 * Copy constructor. 00139 * 00140 * Create a window from another channel. 00141 * 00142 * @param other the channel to be copied. 00143 * @param fromRow initial row of the other channel to be copied 00144 * @param fromCol initial column of the other channel to be copied 00145 * @param toRow last row to be copied of the other channel 00146 * @param toCol last column to be copied of the other channel 00147 * 00148 * Example: 00149 * \code 00150 * cvr::channel m(4,6,0); // channel with 24 elements 00151 * // ... 00152 * // initialize channel with: 00153 * // 0 1 2 3 4 5 00154 * // 2 1 5 4 0 3 00155 * // 1 2 1 2 3 2 00156 * // 3 3 2 1 2 3 00157 * 00158 * cvr::channel sm(m,1,3,0,2) // this line will lead to the 00159 * // following contents for sm: 00160 * // 1 2 3 00161 * // 1 5 4 00162 * // 2 1 2 00163 * \endcode 00164 * 00165 */ 00166 channel(const channel& other, 00167 const int fromRow, 00168 const int fromCol=0, 00169 const int toRow=MaxIndex, 00170 const int toCol=MaxIndex); 00171 00172 /** 00173 * Copy constructor. 00174 */ 00175 channel(const channel& other); 00176 00177 /** 00178 * Copy constructor. 00179 * 00180 * Create a window from another channel. 00181 * 00182 * @param other the channel to be copied. 00183 * @param from initial coordinates of the window. 00184 * @param to final coordinates of the window. 00185 */ 00186 channel(const channel& other, 00187 const ipoint& from, 00188 const ipoint& to); 00189 00190 /** 00191 * Returns the name of this type. 00192 */ 00193 virtual const std::string& name() const; 00194 00195 /** 00196 * Create a clone of this channel 00197 * @return a pointer to a copy of this matrix 00198 */ 00199 virtual channel* clone() const; 00200 00201 /** 00202 * Create a new empty channel 00203 * @return a pointer to new channel 00204 */ 00205 virtual channel* newInstance() const; 00206 00207 /** 00208 * Copy the \a other channel8 by casting each of its elements. 00209 * 00210 * The elements of the channel8 will be also multiplied by 1/255. 00211 * 00212 * @param other the channel8 to be casted 00213 * @return a reference to this channel 00214 * 00215 * Example: 00216 * \code 00217 * cvr::channel8 matA(10,10,255); // a channel8 00218 * cvr::channel matB; // a channel 00219 * 00220 * matB.castFrom(matA); // this will copy matA in matB!! 00221 * // and all elements will have 1.0f 00222 * \endcode 00223 */ 00224 channel& castFrom(const channel8& other); 00225 00226 /** 00227 * Cast the image to an channel. 00228 * It extracts the intensity channel of the image, defined as 00229 * (R+G+B)/3, where R, G, and B are the red, green and blue components 00230 * of the pixel. 00231 * 00232 * The elements of the resulting channel will be between 0.0f (black) and 00233 * 1.0f (white). 00234 * 00235 * @param other the image to be casted 00236 * @return a reference to this channel 00237 */ 00238 channel& castFrom(const image& other); 00239 00240 /** 00241 * Copy the \a other matrix by casting each of its elements 00242 * @param other The matrix to be casted 00243 * @return a reference to this channel 00244 */ 00245 template<typename U> 00246 inline channel& castFrom(const matrix<U>& other); 00247 00248 /** 00249 * Apply a gray valued transformation which maps the given intervall to 00250 * [0.0,1.0] (default) or the explicitly given "destination" interval 00251 * 00252 * @param minVal the lower limit of the original data interval 00253 * @param maxVal the higher limit of the original data interval 00254 * @param minDest the lower limit of the mapped interval (default 0.0f) 00255 * @param maxDest the higher limit of the mapped interval (default 1.0f) 00256 * @return a reference to this object 00257 * 00258 * For example, if you want to map the interval [-1.0f,2.0f] to 00259 * the "usual" interval [0.0,1.0] just use one of following methods: 00260 * 00261 * \code 00262 * cvr::channel chnl; 00263 * // ... 00264 * chnl.mapLinear(-1.0f,2.0f,0.0,1.0); // map [-1,2] to [0,1] 00265 * // this is equivalent to (due to default "destination" interval) 00266 * chnl.mapLinear(-1.0f,2.0f); 00267 * \endcode 00268 * 00269 * Not that you can use this method to "invert" your gray values with 00270 * \code 00271 * chnl.mapLinear(0.0f,1.0f,1,0f,0.0f); // map [0,1] to [1,0] 00272 * // this is equivalent to (due to default "destination" interval) 00273 * chnl.mapLinear(1.0f,0.0f); 00274 * \endcode 00275 * 00276 */ 00277 channel& mapLinear(const float& minVal, const float& maxVal, 00278 const float& minDest=0.0f, const float& maxDest=1.0f); 00279 00280 00281 /** 00282 * Apply a gray valued transformation which maps the given 00283 * intervall of the other channel into [0.0,1.0] (default) or the 00284 * explicitly given "destination" interval in this channel. 00285 * 00286 * @param other the other channel which values are to be mapped into 00287 * the new interval 00288 * @param minVal the lower limit of the original data interval 00289 * @param maxVal the higher limit of the original data interval 00290 * @param minDest the lower limit of the mapped interval (default 0.0f) 00291 * @param maxDest the higher limit of the mapped interval (default 1.0f) 00292 * @return a reference to this object 00293 * 00294 * For example, if you want to map the interval [-1.0f,2.0f] to 00295 * the "usual" interval [0.0,1.0] just use one of following methods: 00296 * 00297 * \code 00298 * cvr::channel chnl; 00299 * // ... 00300 * chnl.mapLinear(-1.0f,2.0f,0.0,1.0); // map [-1,2] to [0,1] 00301 * // this is equivalent to (due to default "destination" interval) 00302 * chnl.mapLinear(-1.0f,2.0f); 00303 * \endcode 00304 * 00305 * Not that you can use this method to "invert" your gray values with 00306 * \code 00307 * chnl.mapLinear(0.0f,1.0f,1,0f,0.0f); // map [0,1] to [1,0] 00308 * // this is equivalent to (due to default "destination" interval) 00309 * chnl.mapLinear(1.0f,0.0f); 00310 * \endcode 00311 * 00312 */ 00313 template<typename U> 00314 channel& mapLinear(const matrix<U>& other, 00315 const U& minVal, const U& maxVal, 00316 const float& minDest=0.0f, const float& maxDest=1.0f); 00317 00318 }; 00319 00320 template<class U> 00321 channel& channel::castFrom(const matrix<U>& other) { 00322 matrix<value_type>::castFrom(other); 00323 return *this; 00324 } 00325 00326 /* 00327 * Apply a gray valued transformation which maps the given intervall to 00328 * [0.0,1.0] (default) or the explicitly given "destination" interval 00329 * @param minVal the lower limit of the original data interval 00330 * @param maxVal the higher limit of the original data interval 00331 * @param minDest the lower limit of the mapped interval (default 0.0f) 00332 * @param maxDest the higher limit of the mapped interval (default 1.0f) 00333 * @return a reference to this object 00334 */ 00335 template<class U> 00336 channel& channel::mapLinear(const matrix<U>& other, 00337 const U& minVal, const U& maxVal, 00338 const float& minDest,const float& maxDest) { 00339 00340 allocate(other.size()); 00341 00342 iterator it; 00343 typename vector<U>::const_iterator cit,eit; 00344 int y; 00345 00346 float tm,tb; 00347 00348 if (maxVal != minVal) { 00349 tm = (maxDest-minDest)/static_cast<float>(maxVal-minVal); 00350 } else { 00351 tm = 1.0f; 00352 } 00353 00354 tb = maxDest-maxVal*tm; 00355 00356 const float m=tm; 00357 const float b=tb; 00358 00359 // check possible speed improvements (unnecessary computations avoided) 00360 00361 if (b == 0.0f) { 00362 for (y=0,it=begin();y<other.rows();++y) { 00363 const vector<U>& vct=other.getRow(y); 00364 for (cit=vct.begin(),eit=vct.end();cit!=eit;++cit,++it) { 00365 (*it)=static_cast<float>((*cit)*m); 00366 } 00367 } 00368 } else if (m == 1.0f) { 00369 for (y=0,it=begin();y<other.rows();++y) { 00370 const vector<U>& vct=other.getRow(y); 00371 for (cit=vct.begin(),eit=vct.end();cit!=eit;++cit,++it) { 00372 (*it)=static_cast<float>((*cit)+b); 00373 } 00374 } 00375 } else { 00376 for (y=0,it=begin();y<other.rows();++y) { 00377 const vector<U>& vct=other.getRow(y); 00378 for (cit=vct.begin(),eit=vct.end();cit!=eit;++cit,++it) { 00379 (*it)=static_cast<float>((*cit)*m+b); 00380 } 00381 } 00382 } 00383 return (*this); 00384 } 00385 00386 00387 00388 } 00389 00390 #endif 00391