CVR-Lib last update 20 Sep 2009

cvrChannelC.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   cvrChannelC.h
00044  *         Contains the data structure to represent complex valued channels
00045  *         with float as type for the real and imaginary components.
00046  * \author Pablo Alvarado
00047  * \date   13.10.2007
00048  *
00049  * $Id: cvrChannelC.h,v 1.1 2007/10/14 02:44:14 alvarado Exp $
00050  */
00051 
00052 #ifndef _CVR_CHANNEL_C_H_
00053 #define _CVR_CHANNEL_C_H_
00054 
00055 #include "cvrMatrix.h"
00056 #include "cvrChannel.h"
00057 #include "cvrChannelC.h"
00058 #include "cvrComplex.h"
00059 #include "cvrTypes.h"
00060 
00061 namespace cvr {
00062   class channel8;
00063   class image;
00064 
00065   /**
00066    * Complex channel.
00067    *
00068    * This class is identical to a matrix of cvr::fcomplex except for the
00069    * method castFrom(channel8).
00070    *
00071    * The typical value range is between 0.0f and 1.0f for both, real and
00072    * imaginary components (see cvr::image for more information).
00073    *
00074    * @see cvr::image, cvr::channel8
00075    *
00076    * @ingroup gAggregate
00077    * @ingroup gImageProcessing
00078    */
00079   class channelC : public matrix< fcomplex > {
00080   public:
00081 
00082     /**
00083      * Default constructor creates an empty channel
00084      */
00085     channelC();
00086 
00087     /**
00088      * Create a connected \c rows x \c cols channel and leave the data
00089      * uninitialized.
00090      *
00091      * @param rows number of rows of the channel
00092      * @param cols number of columns of the channel
00093      */
00094     channelC(const int rows,const int cols);
00095 
00096     /**
00097      * Create a connected \c size.y x \c size.x channel and initializes
00098      * all elements with \a iniValue
00099      *
00100      * @param size cvr::ipoint with the size of the channel
00101      *             (size.x is the number of columns and
00102      *              size.y the number of rows)
00103      */
00104     channelC(const ipoint& size);
00105 
00106     /**
00107      * Create a connected \c rows x \c cols channel
00108      * and initializes all elements with \a iniValue
00109      *
00110      * @param rows number of rows of the channel
00111      * @param cols number of columns of the channel
00112      * @param iniValue all elements will be initialized with this value
00113      */
00114     channelC(const int rows,const int cols,const fcomplex& iniValue);
00115 
00116     /**
00117      * Create a connected \c size.y x \c size.x channel and initializes
00118      * all elements with \a iniValue
00119      *
00120      * @param size cvr::ipoint with the size of the channel
00121      *             (size.x is the number of columns and
00122      *              size.y the number of rows)
00123      * @param iniValue all elements will be initialized with this value
00124      */
00125     channelC(const ipoint& size,const fcomplex& iniValue);
00126 
00127     /**
00128      * Create a connected \c rows x \c cols channel and initializes all
00129      * elements with the data ipointed by \a data.  The first
00130      * \a cols-elements of the data will be copied on the first row,
00131      * the next ones on the second row and so on.
00132      *
00133      * @param rows number of rows of the channel
00134      * @param cols number of columns of the channel
00135      * @param data pointer to the memory block with the data to be initialized
00136      * with.
00137      */
00138     channelC(const int rows,const int cols,const fcomplex data[]);
00139 
00140     /**
00141      * Copy constructor.
00142      *
00143      * Create a window from another channelC.
00144      *
00145      * @param other   the channel to be copied.
00146      * @param fromRow initial row of the other channel to be copied
00147      * @param fromCol initial column of the other channel to be copied
00148      * @param toRow   last row to be copied of the other channel
00149      * @param toCol   last column to be copied of the other channel
00150      *
00151      * Example:
00152      * \code
00153      * cvr::channelC m(4,6,0); // channel with 24 elements
00154      * // ...
00155      * // initialize channel with:
00156      * //        0  1  2  3  4  5
00157      * //        2  1  5  4  0  3
00158      * //        1  2  1  2  3  2
00159      * //        3  3  2  1  2  3
00160      *
00161      * cvr::channelC sm(m,1,3,0,2)  // this line will lead to the
00162      * //                             following contents for sm:
00163      * //        1  2  3
00164      * //        1  5  4
00165      * //        2  1  2
00166      * \endcode
00167      *
00168      */
00169     channelC(const channelC& other,
00170              const int fromRow,
00171              const int fromCol=0,
00172              const int toRow=MaxIndex,
00173              const int toCol=MaxIndex);
00174 
00175     /**
00176      * Copy constructor.
00177      */
00178     channelC(const channelC& other);
00179 
00180     /**
00181      * Copy constructor.
00182      *
00183      * Create a window from another channel.
00184      *
00185      * @param other   the channel to be copied.
00186      * @param from    initial coordinates of the window.
00187      * @param to      final coordinates of the window.
00188      */
00189     channelC(const channelC& other,
00190              const ipoint& from,
00191              const ipoint& to);
00192 
00193     /**
00194      * Returns the name of this type.
00195      */
00196     virtual const std::string& name() const;
00197 
00198     /**
00199      * Create a clone of this channel
00200      * @return a pointer to a copy of this matrix
00201      */
00202     virtual channelC* clone() const;
00203 
00204     /**
00205      * Create a new empty channel
00206      * @return a pointer to new channel
00207      */
00208     virtual channelC* newInstance() const;
00209 
00210     /**
00211      * Copy the \a other channel8 by casting each of its elements.
00212      *
00213      * The elements of the channel8 will be also multiplied by 1/255.
00214      *
00215      * @param other the channel8 to be casted
00216      * @return a reference to this channel
00217      *
00218      * Example:
00219      * \code
00220      *   cvr::channel8 matA(10,10,255); // a channel8
00221      *   cvr::channel  matB;            // a channel
00222      *
00223      *   matB.castFrom(matA);         // this will copy matA in matB!!
00224      *                                // and all elements will have 1.0f
00225      * \endcode
00226      */
00227     channelC& castFrom(const channel8& other);
00228 
00229     /**
00230      * Cast the image to an channelC.
00231      * It extracts the intensity channel of the image, defined as
00232      * (R+G+B)/3, where R, G, and B are the red, green and blue components
00233      * of the pixel.
00234      *
00235      * The elements of the resulting channel will be between 0.0f (black) and
00236      * 1.0f (white) for the real part and zero as imaginary part.
00237      *
00238      * @param other the image to be casted
00239      * @return a reference to this channel
00240      */
00241     channelC& castFrom(const image& other);
00242 
00243     /**
00244      * Copy the \a other matrix by casting each of its elements.
00245      *
00246      * @param other The matrix to be casted
00247      * @return a reference to this channel
00248      */
00249     template<typename U>
00250     inline channelC& castFrom(const matrix<U>& other);
00251 
00252     /**
00253      * Extract the real part of each pixel as a channel
00254      */
00255     void getReal(channel& real) const;
00256 
00257     /**
00258      * Extract the imaginary part of each pixel as a channel
00259      */
00260     void getImag(channel& imag) const;
00261 
00262     /**
00263      * Extract the squared magnitude of each pixel.
00264      *
00265      * This method is faster than getAbs() as it avoids taking the square root
00266      * of each pixel.
00267      */
00268     void getNorm(channel& smag) const;
00269 
00270     /**
00271      * Extract the magnitude of each pixel.
00272      *
00273      * This method is slower than getSqrMagnitude() as it has to apply the
00274      * square root to each pixel.
00275      */
00276     void getAbs(channel& mag) const;
00277 
00278     /**
00279      * Extract the argument of each pixel (its angle).
00280      *
00281      * This method is slow as it needs to apply the arctan to each pixel.
00282      *
00283      * For time critical applications, use the getArgumentFast, which makes use
00284      * of the cvr::arctanLUT, but is not as precise as this one.
00285      */
00286     void getArg(channel& arg) const;
00287 
00288     /**
00289      * Extract the argument of each pixel (its angle) in a fast way.
00290      *
00291      * This method requires that both the real and imaginary parts lie within
00292      * the interval [0,1].
00293      *
00294      * This method makes use of the cvr::arctanLUT to accelerate the
00295      * computation of the angle.  If you need very precise angular values, use
00296      * the getArg() method instead.
00297      */
00298     void getArgFast(channel& arg) const;
00299 
00300     /**
00301      * Set the real and imaginary parts from two different channels.
00302      *
00303      * Both channels must have the same size.  If they are not, the method
00304      * returns \c false.
00305      */
00306     bool set(const channel& real,const channel& imag);
00307 
00308     /**
00309      * Get the real and imaginary parts as two different channels.
00310      */
00311     void get(channel& real,channel& imag) const;
00312 
00313     /**
00314      * Apply a gray valued transformation which maps the given interval to
00315      * [0.0,1.0] (default) or the explicitly given "destination" interval
00316      *
00317      * @param minVal the lower limit of the original data interval
00318      * @param maxVal the higher limit of the original data interval
00319      * @param minDest the lower limit of the mapped interval (default 0.0f)
00320      * @param maxDest the higher limit of the mapped interval (default 1.0f)
00321      * @return a reference to this object
00322      *
00323      * A linear mapping is applied, where now the slope and offset are complex
00324      * values computed by and analytical extension of the real counterpart.
00325      *
00326      * For example, if you want to map the interval [-1.0f,2.0f] to the "usual"
00327      * interval [0.0,1.0] just use one of following methods:
00328      *
00329      * \code
00330      * cvr::channel chnl;
00331      * // ...
00332      * chnl.mapLinear(-1.0f,2.0f,0.0,1.0); // map [-1,2] to  [0,1]
00333      * // this is equivalent to (due to default "destination" interval)
00334      * chnl.mapLinear(-1.0f,2.0f);
00335      * \endcode
00336      *
00337      * Not that you can use this method to "invert" your gray values with
00338      * \code
00339      * chnl.mapLinear(0.0f,1.0f,1,0f,0.0f); // map [0,1] to  [1,0]
00340      * // this is equivalent to (due to default "destination" interval)
00341      * chnl.mapLinear(1.0f,0.0f);
00342      * \endcode
00343      *
00344      */
00345     channelC& mapLinear(const fcomplex& minVal,
00346                         const fcomplex& maxVal,
00347                         const fcomplex& minDest=0.0f,
00348                         const fcomplex& maxDest=1.0f);
00349 
00350 
00351     /**
00352      * Apply a gray valued transformation which maps the given
00353      * intervall of the other channel into [0.0,1.0] (default) or the
00354      * explicitly given "destination" interval in this channel.
00355      *
00356      * @param other the other channel which values are to be mapped into
00357      *              the new interval
00358      * @param minVal the lower limit of the original data interval
00359      * @param maxVal the higher limit of the original data interval
00360      * @param minDest the lower limit of the mapped interval (default 0.0f)
00361      * @param maxDest the higher limit of the mapped interval (default 1.0f)
00362      * @return a reference to this object
00363      *
00364      * For example, if you want to map the interval [-1.0f,2.0f] to
00365      * the "usual" interval [0.0,1.0] just use one of following methods:
00366      *
00367      * \code
00368      * cvr::channel chnl;
00369      * // ...
00370      * chnl.mapLinear(-1.0f,2.0f,0.0,1.0); // map [-1,2] to  [0,1]
00371      * // this is equivalent to (due to default "destination" interval)
00372      * chnl.mapLinear(-1.0f,2.0f);
00373      * \endcode
00374      *
00375      * Not that you can use this method to "invert" your gray values with
00376      * \code
00377      * chnl.mapLinear(0.0f,1.0f,1,0f,0.0f); // map [0,1] to  [1,0]
00378      * // this is equivalent to (due to default "destination" interval)
00379      * chnl.mapLinear(1.0f,0.0f);
00380      * \endcode
00381      *
00382      */
00383     template<typename U>
00384     channelC& mapLinear(const matrix<U>& other,
00385                         const U& minVal,
00386                         const U& maxVal,
00387                         const fcomplex& minDest=0.0f,
00388                         const fcomplex& maxDest=1.0f);
00389 
00390   };
00391 
00392   template<class U>
00393   channelC& channelC::castFrom(const matrix<U>& other) {
00394     matrix<value_type>::castFrom(other);
00395     return *this;
00396   }
00397 
00398   /*
00399    * Apply a gray valued transformation which maps the given intervall to
00400    * [0.0,1.0] (default) or the explicitly given "destination" interval
00401    * @param minVal the lower limit of the original data interval
00402    * @param maxVal the higher limit of the original data interval
00403    * @param minDest the lower limit of the mapped interval (default 0.0f)
00404    * @param maxDest the higher limit of the mapped interval (default 1.0f)
00405    * @return a reference to this object
00406    */
00407   template<class U>
00408   channelC& channelC::mapLinear(const matrix<U>& other,
00409                                 const U& minVal, const U& maxVal,
00410                                 const fcomplex& minDest,
00411                                 const fcomplex& maxDest) {
00412 
00413     allocate(other.size());
00414 
00415     iterator it;
00416     typename vector<U>::const_iterator cit,eit;
00417     int y;
00418 
00419     fcomplex tm,tb;
00420 
00421     if (maxVal != minVal) {
00422       tm = (maxDest-minDest)/static_cast< fcomplex >(maxVal-minVal);
00423     } else {
00424       tm = 1.0f;
00425     }
00426 
00427     tb = maxDest-maxVal*tm;
00428 
00429     const fcomplex m=tm;
00430     const fcomplex b=tb;
00431 
00432     // check possible speed improvements (unnecessary computations avoided)
00433 
00434     if (b == 0.0f) {
00435       for (y=0,it=begin();y<other.rows();++y) {
00436         const vector<U>& vct=other.getRow(y);
00437         for (cit=vct.begin(),eit=vct.end();cit!=eit;++cit,++it) {
00438           (*it)=static_cast< fcomplex >((*cit)*m);
00439         }
00440       }
00441     } else if (m == 1.0f) {
00442       for (y=0,it=begin();y<other.rows();++y) {
00443         const vector<U>& vct=other.getRow(y);
00444         for (cit=vct.begin(),eit=vct.end();cit!=eit;++cit,++it) {
00445           (*it)=static_cast< fcomplex >((*cit)+b);
00446         }
00447       }
00448     } else {
00449       for (y=0,it=begin();y<other.rows();++y) {
00450         const vector<U>& vct=other.getRow(y);
00451         for (cit=vct.begin(),eit=vct.end();cit!=eit;++cit,++it) {
00452           (*it)=static_cast< fcomplex >((*cit)*m+b);
00453         }
00454       }
00455     }
00456     return (*this);
00457   }
00458 
00459 
00460 
00461 }
00462 
00463 #endif
00464 

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