CVR-Lib last update 20 Sep 2009

cvrChannel.h

Go to the documentation of this file.
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 

Generated on Sun Sep 20 22:07:59 2009 for CVR-Lib by Doxygen 1.5.8