Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

MathOps.H

Go to the documentation of this file.
00001 /*!@file Image/MathOps.H Mathematical operations on Image
00002  */
00003 
00004 // //////////////////////////////////////////////////////////////////// //
00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00006 // University of Southern California (USC) and the iLab at USC.         //
00007 // See http://iLab.usc.edu for information about this project.          //
00008 // //////////////////////////////////////////////////////////////////// //
00009 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00010 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00011 // in Visual Environments, and Applications'' by Christof Koch and      //
00012 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00013 // pending; application number 09/912,225 filed July 23, 2001; see      //
00014 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00015 // //////////////////////////////////////////////////////////////////// //
00016 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00017 //                                                                      //
00018 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00019 // redistribute it and/or modify it under the terms of the GNU General  //
00020 // Public License as published by the Free Software Foundation; either  //
00021 // version 2 of the License, or (at your option) any later version.     //
00022 //                                                                      //
00023 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00024 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00025 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00026 // PURPOSE.  See the GNU General Public License for more details.       //
00027 //                                                                      //
00028 // You should have received a copy of the GNU General Public License    //
00029 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00030 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00031 // Boston, MA 02111-1307 USA.                                           //
00032 // //////////////////////////////////////////////////////////////////// //
00033 //
00034 // Primary maintainer for this file: Rob Peters <rjpeters@klab.caltech.edu>
00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Image/MathOps.H $
00036 // $Id: MathOps.H 10794 2009-02-08 06:21:09Z itti $
00037 //
00038 
00039 #ifndef IMAGE_MATHOPS_H_DEFINED
00040 #define IMAGE_MATHOPS_H_DEFINED
00041 
00042 #include "Image/Image.H"
00043 #include "Util/Promotions.H"
00044 #include <vector>
00045 
00046 class Dims;
00047 template <class T> class Point2D;
00048 class Rectangle;
00049 template <class T> class Image;
00050 template <class T> class Range;
00051 
00052 //! fill with a generating function: x = func() for each x in image
00053 /*! returns a copy of the functor object after having been called */
00054 template <class T, class F>
00055 inline F fill(Image<T>& x, F func);
00056 
00057 //! apply a function in-place: x = func(x) for each x in image
00058 /*! returns a copy of the functor object after having been called */
00059 template <class T, class F>
00060 inline F apply(Image<T>& x, F func);
00061 
00062 //! apply a function out-of-place: y = func(x) for x in input, y in output
00063 template <class T2, class T, class F>
00064 inline Image<T2> transform(const Image<T>& x, F func);
00065 
00066 //! Returns the sum of all input pixels.
00067 template <class T>
00068 double sum(const Image<T>& a);
00069 
00070 //! Get the average of all input pixels.
00071 template <class T>
00072 double mean(const Image<T>& a);
00073 
00074 //! compute standard deviation of pixel values over image
00075 template <class T>
00076 double stdev(const Image<T>& a);
00077 
00078 //! Get the min/max range of the input pixels.
00079 /*! This provides similar functionality to Image<T>::getMinMax(). */
00080 template <class T>
00081 Range<T> rangeOf(const Image<T>& img);
00082 
00083 //! Linearly remap pixels from the source to dest dynamic ranges.
00084 /*! This is similar to, but more general than, Image<T>::normalize(). In
00085     effect, Image<T>::normalize() always assumes that the source range is
00086     the image's own min/max range. In contrast, remapRange() allows one to
00087     find the global min/max across a range of images, and then use that as
00088     the source range while normalizing each the images using that range. */
00089 template <class T>
00090 Image<T> remapRange(const Image<T>& img,
00091                     const Range<T>& from, const Range<T>& to);
00092 
00093 //! Square each element of the input image.
00094 template <class T>
00095 Image<T> squared(const Image<T>& a);
00096 
00097 //! Raise each element of the input image to the given power.
00098 template <class T>
00099 Image<typename promote_trait<T,float>::TP>
00100 toPower(const Image<T>& a, double pow);
00101 
00102 //! Raise pixels in given region of an input image to the given power. Pass a vector of 2D points that define the region of the image that you want to enhance.
00103 template <class T>
00104 Image<typename promote_trait<T,float>::TP>
00105 toPowerRegion(const Image<T>& a, double pow, std::vector<Point2D<int> > region);
00106 
00107 
00108 //! Take absolute value of every pixel.
00109 template <class T>
00110 Image<T> abs(const Image<T>& a);
00111 
00112 //! Compute exp(pixel / (2 * sigma^2)) for every pixel.
00113 template <class T>
00114 Image<typename promote_trait<T,float>::TP>
00115 hmaxActivation(const Image<T>& a, const float sigma);
00116 /*
00117 //! Returns abs(b - c).
00118 //template <class T>
00119 //Image<T> absDiff(const Image<T>& b, const Image<T>& c);
00120 */
00121 //! Returns abs(b - c) for each color channel
00122 template <class T_or_RGB>
00123 Image<T_or_RGB> absDiff(const Image<T_or_RGB>& b,
00124                         const Image<T_or_RGB>& c);
00125 
00126 //! Returns (b - c), clamping to zero all negative values.
00127 //template <class T>
00128 //Image<T> clampedDiff(const Image<T>& b, const Image<T>& c);
00129 
00130 //! Returns (b - c) for each color channel, clamping to zero all neg. values
00131 template <class T_or_RGB>
00132 Image<T_or_RGB> clampedDiff(const Image<T_or_RGB>& b,
00133                             const Image<T_or_RGB>& c);
00134 
00135 //! Returns (val - a).
00136 template <class T>
00137 Image<T> binaryReverse(const Image<T>& a, const T val);
00138 
00139 //! Returns (b + c) / 2, clean & prevents overflows.
00140 template <class T>
00141 Image<T> average(const Image<T>& b, const Image<T>& c);
00142 
00143 //! Returns (a*w + b) / 2, the weighted average between images
00144 template <class T>
00145 Image<T> averageWeighted(Image<T>& a, const Image<T>& b, T *aWeight);
00146 
00147 //! Returns max(a, b), element by element.
00148 template <class T_or_RGB>
00149 Image<T_or_RGB> takeMax(const Image<T_or_RGB>& a,
00150                         const Image<T_or_RGB>& b);
00151 
00152 //! Returns min(a, b), element by element.
00153 template <class T>
00154 Image<T> takeMin(const Image<T>& a, const Image<T>& b);
00155 
00156 //! Compute energy for quadrature pair (sqrt(img1^2 + img2^2)).
00157 template <class T_or_RGB>
00158 Image<T_or_RGB> quadEnergy(const Image<T_or_RGB>& img1,
00159                            const Image<T_or_RGB>& img2);
00160 
00161 //! RMS error between arr1 and arr2.
00162 template <class T>
00163 double RMSerr(const Image<T>& arr1, const Image<T>& arr2);
00164 
00165 //! Create transparency overlay of two images
00166 /*! by laying top over bottom with transparency of top set to
00167  trans. A new image will be returned (use 0 to 100 for percent
00168  transparency). NOTE: top and bottom must be the same size!
00169  this function only works for grey scale images */
00170 template <class T>
00171 Image<T> overlay(const Image<T>& top, const Image<T>& bottom,
00172                  const float trans);
00173 
00174 //! sum pixels along the X and Y axes (sumX, sumY) and in total (return value)
00175 /*!@param img is a w x h size image
00176   @param sumX will return a vector of length w with the sum over the rows of img
00177   @param sumY will return a vector of length h with the sum over the columns*/
00178 template <class T>
00179 float sumXY(const Image<T>& img, std::vector<float>& sumX,
00180             std::vector<float>& sumY);
00181 
00182 //! Returns Euclidean distance between two images
00183 /*! Returns sqrt(sum_over_pixels((img1[i] - img2[i])^2)) */
00184 template <class T>
00185 double distance(const Image<T> &img1, const Image<T> &img2);
00186 
00187 //! Returns weighted Euclidean distance between two images
00188 /*! Returns sqrt(sum_over_pixels(weight[i] * (img1[i] - img2[i])^2)) */
00189 template <class T>
00190 double distance(const Image<T> &img1, const Image<T> &img2,
00191                 const Image<float> &weight);
00192 
00193 //! Returns the correlation coefficient r^2 of the two images.
00194 double corrcoef(const Image<float>& img1, const Image<float>& img2);
00195 
00196 //! Returns the cross-correlation coefficient r between two patches
00197 /*! Note that the computations done here differ from what is done in
00198   corrcoeff, in that a signed correlation coefficient is returned
00199   (between -1 and 1), and we add a convention that if both patches
00200   have zero variance then the correlation is 1. If only one patch has
00201   zero variance then the correlation is zero. Current implementation
00202   requires that the patch fits within both image bounds, and assumes a
00203   small patch size so that it will not attempt to use a faster
00204   FFT-based implementation which can save time with larger patches.
00205   @param img1 first image
00206   @param topleft1 coordinates of top-left corner of patch in img1
00207   @param patchdims dimensions of patch
00208   @param img2 second image
00209   @param topleft2 coordinates of top-left corner of patch in img2
00210   @param eps epsilon used to determine whether patch variance is zero */
00211 template <class T>
00212 double corrpatch(const Image<T>& img1, const Point2D<int>& topleft1,
00213                  const Dims& patchdims, const Image<T>& img2,
00214                  const Point2D<int>& topleft2, const double eps = 1.0e-20);
00215 
00216 //! return correlation matrix and means for input samples
00217 /*! This class will take a set of images and produce the eigen / correlation
00218     matrices. The input provided consists of a set of images:
00219 
00220     (1) An image for each feature dimension
00221     (2) Multiple sets of (1) for each frame sample
00222 
00223     That is, you provide a cardinal set of images that contains multiple
00224     image frames as well as feature maps for each frame.
00225 
00226     This class returns an image that is the eigen matrix given the samples
00227     you have provided. It also returns the mean values per dimension. The
00228     usefulness of this is that one can compute and fit a gaussian to
00229     the data. This can be used for instance in likelyhood estimation.
00230 
00231     The return eigen matrix is either a basic covariance matrix with
00232     un-normalized values useful for likelyhood estimation OR you can
00233     opt to have it normalize the matrix by the product of the standard
00234     deviations. This gives a pearson r correlation coefficent.
00235 
00236     note on input: The set is a nest vector of images. It should be of the form
00237     in c++ notation
00238 
00239           baseImages[frames][features]
00240 
00241     Thus, the first nesting should index each frame while the second should
00242     index each feature image.
00243 
00244     We compute covariance using an augmented method from Hayes 5th Ed. 1991
00245 
00246     @param baseImages The set of all input images
00247     @param baseCorr a return image that is the eigen matrix
00248     @param baseMean a return image that is the set of means
00249     @param baseSTD a return image that is the set of independant standard dev.
00250     @param baseSS a return image that contains the sum of squares
00251     @param baseN a return uint that is the total sample size
00252     @param returnR Should we return the normalized R or the eigen matrix
00253 */
00254 
00255 template <class T>
00256 void corrEigenMatrix(const std::vector<std::vector<Image<T> > > &baseImages,
00257                      Image<T> &baseCorr, Image<T> &baseMean,
00258                      Image<T> &baseSTD,  Image<T> &baseSS,
00259                      uint &baseN, bool returnR = false);
00260 
00261 //! Given an eigen matrix and mean matrix, compute a likelyhood image
00262 /*! In this function we take in an image and the statistics of an
00263     exemplar image set. We then use this to find a likelyhood image
00264     which is how much each pixel in the input image is like the exempler
00265     based on probability. High return values mean that a pixel has a high
00266     probability of belonging to the exemplar class.
00267 
00268     Basically, we compute P(x|C) for each pixel assuming baseImages as the
00269     samples and baseCorr as the eigen matrix that describes the distribution
00270     of the original sample. This computes P from the multi-variate gaussian.
00271     The results can be taken and fed into getNormalized bayes image with
00272     the results from a second class to give a true bayes P for each pixel
00273     belonging to one class or the other.
00274 
00275     Note: the non-normalized likelhood image is usefull for certain things
00276     but should not be used in deriving the direct bayed probability
00277 
00278     @param baseImage the image set you wish to find the likelyhood over
00279     @param baseCorr The eigen matrix correlation from the training set
00280     @param baseMean The set of mean values from the training set
00281     @param returnLogLikelyhood Keep numbers sane and return log not e^
00282     @param likelyhoodImage this is the returned likelyhood image
00283     @param nonNormalizedLImage this is a non-normalized likelyhood image
00284 
00285 */
00286 template <class T>
00287 void getLikelyhoodImage(const std::vector<Image<T> > &baseImages,
00288                         const Image<T> &baseCorr, const Image<T> &baseMean,
00289                         const bool returnLogLikelyhood,
00290                         Image<T> &likelyhoodImage,
00291                         Image<T> &nonNormalizedLImage);
00292 
00293 //! Take in two likelyhood images and compute bayes p between them
00294 /*! The idea here is to compute the true bayesian probability of
00295     membership in one image or another given the likelyhood computed in
00296     getLikelyhoodImage. Here we compute the p(C|x) for two classes.
00297 
00298     The idea here is to compute the likelyhood that a pixel belongs to one
00299     class v. another in an input image. You must input two likelyhood images
00300     of the form P(x|C) (as computed in getLikelyhoodImage). Also, you may
00301     input the prior probability P(C) if P(C1) is not P(C2). Otherwise,
00302     it is assumed P(C1) = P(C2).
00303 
00304     The return image has the P for each pixel being in class 1 v. class 2
00305     to get the result the other way, compute 1 - P (pretty easy).
00306 
00307     To compute this, we perform P(C|x) = g(a) where:
00308 
00309     a = ln((P(x|C1)*P(C1))/(P(x|C2)*P(C2)))
00310 
00311     g(a) = 1/(1 + exp(-a))
00312 
00313     This is known as logistic discrimination (Bishop 1995)
00314 
00315     @param classImage1 the likelyhood image of class 1
00316     @param classImage2 the likelyhood image of class 2
00317     @usingLogLikelyhood set to true if using log rather than e^ likelyhood
00318     @param classPrior1 the prior of class 1 (sample numbers)
00319     @param classPrior2 the prior of class 2 (sample numbers)
00320     @param bias This is a simple bias if desired, P(x)' = P(x)*bias
00321 */
00322 template <class T>
00323 Image<T> getNormalizedBayesImage(const Image<T> classImage1,
00324                                  const Image<T> classImage2,
00325                                  const bool usingLogLikelyhood,
00326                                  const T beta,
00327                                  const T classPrior1 = 1.0,
00328                                  const T classPrior2 = 1.0,
00329                                  const T bias        = 1.0);
00330 
00331 //! Take in an image of correlation and standard deviation, give r
00332 /*! You can use this function to give r from an already existing eigen matrix
00333     for instance, one computed from corrEigenMatrix. Thus, you can post hoc
00334     compute r if you opted not to when using corrEigenMatrix. This function
00335     just basically normalizes the eigen matrix by the standard deviation
00336     to give a true pearson r correlation matrix
00337 
00338     @param eigenMatrix The input eigen correlation matrix
00339     @param STDMatrix The input independant standard deviations
00340 */
00341 template <class T>
00342 Image<T> getPearsonRMatrix(const Image<T> &eigenMatrix,
00343                            const Image<T> &STDMatrix);
00344 
00345 //! Augment the bayes image with some beliefs
00346 /*! The belief images should be from 0 to 1 where 0 signifies
00347     complete belief in the reliability of class1 results while 0
00348     signifies absolutly no reliability. This basicially takes the product
00349     of the two as the final augmented belief.
00350 
00351     Using the median point, beliefs can be contracted to single values
00352     for instance, if the input bayes image ranges from 0 to 2, if the median
00353     is specified as 1, then values below 1 will tend to 1 as beleifs decrease
00354     while values above 1, will tend to 1 as beliefs decrease.
00355 
00356     @param bayesImage An image from getNormalizedBayesImage
00357     @param beliefImage1 the belief for class image 1
00358     @param beliefImage2 the belief for class image 2
00359     @param medianPoint a middle point values are squashed to
00360     @param beliefImage The augemented belief image
00361     @param beliefValue a record of the beleif products
00362 */
00363 
00364 template <class T>
00365 void getAugmentedBeliefBayesImage(const Image<T> &bayesImage,
00366                                   const Image<T> &beliefImage1,
00367                                   const Image<T> &beliefImage2,
00368                                   const T medianPoint,
00369                                   Image<T> &beliefImage,
00370                                   Image<T> &beliefValue);
00371 
00372 
00373 
00374 //! Returns peak signal-to-noise ratio
00375 /*! pSNR is computed as 10.log_10(255^2/sigma^2) where
00376   sigma^2=/N.sum(x1_i - x2_i)^2 and is a measure of distortion between
00377   two images */
00378 template <class T>
00379 double pSNR(const Image<T> &img1, const Image<T> &img2);
00380 
00381 //! Returns weighted peak signal-to-noise ratio
00382 /*! This is like the other pSNR() except that it uses the weighted
00383   version of distance() internally */
00384 template <class T>
00385 double pSNR(const Image<T> &img1, const Image<T> &img2,
00386             const Image<float>& weight);
00387 
00388 //! Take square root of all elements
00389 template <class T>
00390 Image<typename promote_trait<T,float>::TP> sqrt(const Image<T>& img);
00391 
00392 //! Take inverse of all elements > eps in abs, 0 otherwise
00393 template <class T>
00394 Image<typename promote_trait<T,float>::TP> inverse(const Image<T>& img,
00395                                                    const T eps);
00396 
00397 //! Take exponential of all pixels
00398 template <class T>
00399 Image<typename promote_trait<T,float>::TP> exp(const Image<T>& img);
00400 
00401 //! Take negative exponential of all pixels, that is exp(-x)
00402 template <class T>
00403 Image<typename promote_trait<T,float>::TP> negexp(const Image<T>& img);
00404 
00405 //! Take natural logarithm of all pixels
00406 template <class T>
00407 Image<typename promote_trait<T,float>::TP> log(const Image<T>& img);
00408 
00409 //! Take base-10 logarithm of all pixels
00410 template <class T>
00411 Image<typename promote_trait<T,float>::TP> log10(const Image<T>& img);
00412 
00413 //! determine the first and last non-zero values and the centroid
00414 /*!@param vect a vector of numbers
00415   @param centroid returns the centroid of vect
00416   @param first returns the position of the first non-zero value in vect
00417   @param last returns the position of the last non-zero value in vect
00418   @return true if we actually found all these values, false if vect
00419   only contains zeros*/
00420 template <class T>
00421 bool getCentroidFirstLast(std::vector<T> vect, float& centroid,
00422                           int& first, int& last);
00423 
00424 //! determine the centroid of all the points in the image
00425 /*! The centroid is rounded to integer pixel positions.
00426   When there are no values > 0 in the img, (-1,-1) is returned
00427   @param boundingBox the bounding box of the object(s) contained in
00428   the image is returned
00429   @param cenX returns the float value of the centroid along the x axis
00430   @param cenY returns the float value of the centroid along the y axis
00431   @return the centroid rounded to integer coordinates*/
00432 template <class T>
00433 Point2D<int> centroid(const Image<T>& img, Rectangle& boundingBox,
00434                  float& cenX, float& cenY);
00435 
00436 //! determine the center of mass of all the points in the image
00437 /*! The centroid is rounded to integer pixel positions.
00438   When there are no values > 0 in the img, (-1,-1) is returned */
00439 template <class T>
00440 Point2D<int> centroid(const Image<T>& img);
00441 
00442 //! Apply a squashing function to the pixel values
00443 /*! The squashing function is a 4th-order polynomial with sigmoidal
00444   shape. Denoting by x a pixel value in the original image and by
00445   y=f(x) the transformed pixel value that will be put in the result
00446   image, the contraints on the polynomial are: 1) f(oldmin)=newmin, 2)
00447   f(oldmax)=newmax, 3) f(oldmid)=newmid, 4) f'(oldmin)=0, and 5)
00448   f'(oldmax)=0. So, typically, the polynomial will have horizontal
00449   slope at both ends of the input range, and will remap the old
00450   min/max to the new min/max while also remapping a user-chosen
00451   mid-point oldmid to newmid. Playing with this mid-point allows the
00452   user to give more emphasis to higher or lower values while
00453   remapping. This is the full form, but two simplified forms are also
00454   available that will compute some of the arguments here from the
00455   input image. Because the main use of this function is when oldmin is
00456   the true minimum value of the input image, and oldmax its true
00457   maximum, here we will not waste time checking for input values
00458   outside this range, and their remapped values are unclear as the
00459   polynomial is unconstrained outside the input range. Internal
00460   remapping is done using floats, and results are converted back (with
00461   possible clamping) to the same type as the original image, so that
00462   this function may be efficiently used to do contrast adjustments in
00463   Image<byte> data. */
00464 template<class T>
00465 Image<T> squash(const Image<T>& src,
00466                 const T oldmin, const T newmin,
00467                 const T oldmid, const T newmid,
00468                 const T oldmax, const T newmax);
00469 
00470 //! Apply a squashing function to the pixel values
00471 /*! In this specialization of the general form of squash(), the old
00472   min/max are computed using getMinMax(). */
00473 template<class T>
00474 Image<T> squash(const Image<T>& src, const T newmin,
00475                 const T oldmid, const T newmid, const T newmax);
00476 
00477 //! Apply a squashing function to the pixel values
00478 /*! In this specialization of the general form of squash(), the old
00479   min/max are computed using getMinMax(), and the new min/max will be
00480   kept equal to the old ones, so that there is no overall change in
00481   range (unless your mid-point is outside that range). */
00482 template<class T>
00483 Image<T> squash(const Image<T>& src, const T oldmid, const T newmid);
00484 
00485 //! Mix between two images based on comparing mask values to a threshold
00486 /*! On every pixel, if mask >= thresh, the returned value is taken
00487   from higher, otherwise it is taken from lower. All three of lower,
00488   highr and mask must have same dims. */
00489 template <class T, class T_or_RGB>
00490 Image<T_or_RGB> thresholdedMix(const Image<T>& mask, const T& thresh,
00491                                const Image<T_or_RGB>& lower,
00492                                const Image<T_or_RGB>& higher);
00493 
00494 //! take the logistic sigmoid 1/(1+e^x(...)) over the image
00495 /*! This is a standard logistic sigmoid with offset o and slope b
00496   @param ima the input image
00497   @param o Offset for this sigmoid
00498   @param b Slope for this sigmoid
00499  */
00500 Image<float> logSig(const Image<float>& ima, float o, float b);
00501 
00502 //! randomly scramble image pixels
00503 template <class T_or_RGB>
00504 Image<T_or_RGB> scramble(const Image<T_or_RGB>& ima);
00505 
00506 //! take in an image and return it's statistically most relevent points
00507 /*!
00508   Input an image to find a monte carlo like map. This will in essence cut
00509   out about half the pixels in a simple quick fashion by applying  the formula:
00510   select if -> pow(pixelValue,bias) > minVal+(maxVal*rand()/RAND_MAX+1.0)
00511   The bias is used to scew the distribution using an exponent
00512   if no bias is given, this method will work more efficently by skipping
00513   the exponent computation over each pixel.
00514   @param ima This is the input probability map
00515   @param coords this is a pointer to a vector which will hold selected coords
00516   @param bais this scews the probability map by pow(pixVal,bias)
00517 
00518 */
00519 int32 findMonteMap(Image<float>& ima,
00520                    std::vector<Point2D<int> >* coords,
00521                    int decimation, float bias);
00522 
00523 //! Take in a vector and decimate it according how many points you want back
00524 /*!
00525   In essence this will decimate a list of coordinates attempting to create a
00526   list of the size in outPoints. Thus, if you have list of 23890 points and
00527   want a list of 300 points, this will take every nth point and create a
00528   list of about this size.
00529   @param coords This is the list of input coordinates
00530   @param cmap This is the final list of coordinates after decimation
00531   @param inPoints this is the input list size
00532   @param outPoints this is how many points you would like out
00533 */
00534 
00535 int32 makeSparceMap(std::vector<Point2D<int> >* coords, std::vector<Point2D<int>*>* cmap,
00536                     std::vector<Point2D<int> >* Oldcoords,
00537                     std::vector<bool>* keep, int inPoints, int outPoints);
00538 
00539 
00540 //! a += b * coeff
00541 template <class T>
00542 void inplaceAddWeighted(Image<T>& a,
00543                         const Image<T>& b, const float coeff);
00544 
00545 //! a = a*a
00546 template <class T>
00547 void inplaceSquare(Image<T>& a);
00548 
00549 //! Replace all occurences of a value 'from' by another value 'to'
00550 void inplaceReplaceVal(Image<byte>& dest,
00551                        const byte& from, const byte& to);
00552 
00553 //! Progressive attenuation of borders by "size" pixels
00554 template <class T_or_RGB>
00555 void inplaceAttenuateBorders(Image<T_or_RGB>& a, int size);
00556 
00557 //! Set borders of "size" pixels to given value
00558 /*! Default value is T's default, which should be T's representation
00559     of zero. */
00560 template <class T_or_RGB>
00561 void inplaceSetBorders(Image<T_or_RGB>& a, const int size,
00562                        const T_or_RGB value = T_or_RGB());
00563 
00564 //! Add speckle noise to array; thresh = 1 for 100% noise
00565 void inplaceSpeckleNoise(Image<byte>& dest,
00566                          const float thresh, const int size,
00567                          const byte noise_color,
00568                          bool random_color=false);
00569 
00570 //! Get a sample which is the max value within a circular aperture
00571 /*! This only works for monochromatic images.
00572   @param center coordinates of the center of the aperture
00573   @param radius radius of the aperture, in pixels */
00574 float getLocalMax(const Image<float>& src,
00575                   const Point2D<int>& center, const int radius);
00576 
00577 //! Get min and max values
00578 template <class T>
00579 void getMinMax(const Image<T>& src, T& mini, T& maxi);
00580 
00581 //! Get min and max values inside and outside a mask
00582 /*! Only pixels with non-zero mask value are considered. */
00583 template <class T>
00584 void getMaskedMinMax(const Image<T>& src, const Image<byte>& mask,
00585                      T& min_in, T& max_in, T& min_out, T& max_out);
00586 
00587 //! Get min, max and average values
00588 template <class T>
00589 void getMinMaxAvg(const Image<T>& src, T& mini, T& maxi, T& avg);
00590 
00591 //! Get min, max, avg within a binary mask
00592 /*! Only the pixels where mask is non-zero are considered. */
00593 template <class T>
00594 void getMaskedMinMaxAvg(const Image<T>& src, const Image<byte> &mask,
00595                         T& mi, T& ma, T& avg);
00596 
00597 //! Get min, max, sum and area values from a continuously-masked image
00598 /*! The sum is the weighted sum of src by mask. Area is the sum of all
00599   non-zero mask values. */
00600 template <class T>
00601 void getMaskedMinMaxSumArea(const Image<T>& src, const Image<float> &mask,
00602                             T& mi, T& ma,
00603                             typename promote_trait<T,float>::TP &sum,
00604                             typename promote_trait<T,float>::TP &area);
00605 
00606 //! Get min, max, average std deviation and some other stats
00607 template <class T>
00608 void getMinMaxAvgEtc(const Image<T>& src, T& xmini, T& xmaxi, T& xavg, T& xstd,
00609                      ushort& minPosX, ushort& minPosY,
00610                      ushort& maxPosX, ushort& maxPosY,
00611                      uint& pixCount);
00612 
00613 //! Check wether all pixels have finite values
00614 /*! This relies on isFinite() being defined for your pixel type
00615   T. In Types.H we define it for the canonical types, and you can
00616   use these canonical definitions to define it for more complex
00617   types (see, for example, the definition in Pixels.H). */
00618 template <class T>
00619 bool isFinite(const Image<T>& src);
00620 
00621 //! find point of max activity and also what that max activity is
00622 template <class T>
00623 void findMax(const Image<T>& src, Point2D<int>& p, T& maxval);
00624 
00625 //! find point of min activity and also what that min activity is
00626 template <class T>
00627 void findMin(const Image<T>& src, Point2D<int>& p, T& minval);
00628 
00629 //! Saturate values < cmin to cmin and > cmax to cmax
00630 template <class T>
00631 void inplaceClamp(Image<T>& dst, const T cmin, const T cmax);
00632 
00633 //! Normalize values between nmin and nmax
00634 template <class T>
00635 void inplaceNormalize(Image<T>& dst, const T nmin, const T nmax);
00636 
00637 //! Normalize values between nmin and nmax, also return oldmin and oldmax
00638 template <class T>
00639 void inplaceNormalize(Image<T>& dst, const T nmin, const T nmax,
00640                       T& oldmin, T& oldmax);
00641 
00642 //! Return true if point p is a local maximum
00643 /*! We just check that the value at p is >= the values of its 4 neighbors */
00644 template <class T>
00645 bool isLocalMax(const Image<T>& src, const Point2D<int>& p);
00646 
00647 //! Saturate values < 0
00648 template <class T>
00649 void inplaceRectify(Image<T>& dst);
00650 
00651 //! Put all values >= 0 into pos and the negated of all vals <= 0 into neg
00652 template <class T>
00653 void splitPosNeg(const Image<T>& src,
00654                  Image<T>& pos, Image<T>& neg);
00655 
00656 //! Cut values < thresh and replace them by val
00657 template <class T>
00658 void inplaceLowThresh(Image<T>& dst,
00659                       const T thresh, const T val = T());
00660 
00661 //! Cut values whose abs is < thresh and replace them by val
00662 template <class T>
00663 void inplaceLowThreshAbs(Image<T>& dst,
00664                          const T thresh, const T val = T());
00665 
00666 //! Pass image through sigmoid: f(x) = x^g / (s + x^h)
00667 template <class T>
00668 void inplaceSigmoid(Image<T>& dst,
00669                     const float g, const float h, const float s);
00670 
00671 //! Tells how many pixels are zero
00672 template <class T>
00673 int emptyArea(const Image<T>& src);
00674 
00675 //! Counts how many pixels are > thresh (in absolute value if absol true)
00676 template <class T>
00677 int countThresh(const Image<T>& src,
00678                 const T thresh, const bool absol = true);
00679 
00680 //! Return a row vector containing the within-column mean of each input column
00681 Image<float> meanRow(const Image<float>& inp);
00682 
00683 //! Return a row vector containing the within-column standard deviation of each input column
00684 Image<float> stdevRow(const Image<float>& inp);
00685 
00686 //! Return the result of adding vector v to each row of matrix M
00687 Image<float> addRow(const Image<float>& M, const Image<float>& v);
00688 
00689 //! Return the result of subtracting vector v from each row of matrix M
00690 Image<float> subtractRow(const Image<float>& M, const Image<float>& v);
00691 
00692 //! Return the result of multiplying each row of matrix M by vector v
00693 Image<float> multiplyRow(const Image<float>& M, const Image<float>& v);
00694 
00695 //! Return the result of dividing each row of matrix M by vector v
00696 Image<float> divideRow(const Image<float>& M, const Image<float>& v);
00697 
00698 // ######################################################################
00699 // ######################################################################
00700 // ##### Inline function definitions
00701 // ######################################################################
00702 // ######################################################################
00703 
00704 // ######################################################################
00705 template <class T, class F>
00706 inline F fill(Image<T>& x, F func)
00707 {
00708   // optimization; see comment in Image<T>::clear()
00709   if (x.isShared())
00710     x = Image<T>(x.getDims(), NO_INIT);
00711 
00712   for (typename Image<T>::iterator itr = x.beginw(), stop = x.endw();
00713        itr != stop; ++itr)
00714     *itr = T(func());
00715 
00716   return func;
00717 }
00718 
00719 // ######################################################################
00720 template <class T, class F>
00721 inline F apply(Image<T>& x, F func)
00722 {
00723   for (typename Image<T>::iterator itr = x.beginw(), stop = x.endw();
00724        itr != stop; ++itr)
00725     *itr = T(func(*itr));
00726 
00727   return func;
00728 }
00729 
00730 // ######################################################################
00731 template <class T2, class T, class F> inline
00732 Image<T2> transform(const Image<T>& x, F func)
00733 {
00734   Image<T2> result(x.getDims(), NO_INIT);
00735 
00736   typename Image<T>::const_iterator sptr = x.begin();
00737   typename Image<T2>::iterator dptr = result.beginw();
00738   typename Image<T2>::iterator stop = result.endw();
00739 
00740   while (dptr != stop)
00741     *dptr++ = func(*sptr++);
00742 
00743   return result;
00744 }
00745 
00746 // ######################################################################
00747 /* So things look consistent in everyone's emacs... */
00748 /* Local Variables: */
00749 /* indent-tabs-mode: nil */
00750 /* End: */
00751 
00752 #endif // !IMAGE_MATHOPS_H_DEFINED

Generated on Sun Nov 22 13:42:34 2009 for iLab Neuromorphic Vision Toolkit by  doxygen 1.4.4