Histogram.C

Go to the documentation of this file.
00001 /*!@file SIFT/Histogram.C Histogram */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00005 // University of Southern California (USC) and the iLab at USC.         //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: James Bonaiuto <bonaiuto@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/SIFT/Histogram.C $
00035 // $Id: Histogram.C 14762 2011-05-03 01:13:16Z siagian $
00036 //
00037 
00038 #include "SIFT/Histogram.H"
00039 #include "Image/DrawOps.H"
00040 
00041 // #######################################################################
00042 Histogram::Histogram(const int size) :
00043   itsHistogram(size)
00044 { clear(); }
00045 
00046 // #######################################################################
00047 Histogram::Histogram(const float* input, const int size) :
00048   itsHistogram(size)
00049 {
00050   for (int i = 0; i < size; i++) itsHistogram[i] = input[i];
00051 }
00052 
00053 // #######################################################################
00054 Histogram::Histogram(std::vector<Histogram> histograms)
00055 {
00056   for(uint i = 0; i < histograms.size(); i++)
00057     {
00058       for (uint j = 0; j < histograms[i].size(); j++) 
00059         itsHistogram.push_back(histograms[i][j]);
00060     }  
00061 }
00062 
00063 // #######################################################################
00064 Histogram::Histogram(const Image<byte>& img) :
00065   itsHistogram(256)
00066 {
00067   Image<float> hi1(img.getWidth(), img.getHeight(), ZEROS);
00068 
00069   int count1 = 0, count2 = 0;
00070   const int w = img.getWidth(); int h = img.getHeight();
00071   for (int i = 0; i < w; i++)
00072     for (int j = 0; j < h; j++)
00073       {
00074         if (img.getVal(i, j) < 1)
00075           { hi1.setVal(i, j, -255); ++ count1; }
00076         else if (img.getVal(i, j) > 254)
00077           { hi1.setVal(i, j, 255); ++ count2; }
00078         itsHistogram[img.getVal(i, j)] += 1.0F;
00079       }
00080 }
00081 
00082 // ######################################################################
00083 Histogram::~Histogram()
00084 {  }
00085 
00086 // #######################################################################
00087 void Histogram::addValue(const uint index, const float value)
00088 {
00089   if (index < itsHistogram.size())
00090     itsHistogram[index] += value;
00091   else
00092     LFATAL("Index %d out of range [0..%"ZU"]",
00093               index, itsHistogram.size()-1);
00094 }
00095 
00096 // #######################################################################
00097 void Histogram::addValueInterp(const float index, const float value)
00098 {
00099   ASSERT(index >= 0.0F && index < float(itsHistogram.size()));
00100   const uint i0 = uint(index);
00101   const float di = index - float(i0);
00102   uint i1 = i0 + 1; if (i1 >= itsHistogram.size()) i1 = 0;
00103 
00104   itsHistogram[i0] += value * (1.0F - di);
00105   itsHistogram[i1] += value * di;
00106 }
00107 
00108 // #######################################################################
00109 void Histogram::fill(const Image<byte>& img)
00110 {
00111   // make sure the histogram has the size 256
00112   itsHistogram.clear();
00113   itsHistogram.resize(256);
00114 
00115   int w = img.getWidth(); int h = img.getHeight();
00116   for (int i = 0; i < w; i++)
00117     for (int j = 0; j < h; j++)
00118         itsHistogram[img.getVal(i, j)] += 1.0F;
00119 }
00120 
00121 // #######################################################################
00122 Image<byte> Histogram::getHistogramImage(const int w, const int h,
00123                                          const float mini, const float maxi)
00124 {
00125   if (uint(w) < itsHistogram.size())
00126     LFATAL("not enough width to display the histogram properly");
00127   int dw = w / itsHistogram.size();
00128 
00129   Image<byte> res(w, h, ZEROS);
00130   //res.clear(255);
00131 
00132   // draw lines for 10% marks:
00133   for (int j = 0; j < 10; j++)
00134     drawLine(res, Point2D<int>(0, int(j * 0.1F * h)),
00135              Point2D<int>(w-1, int(j * 0.1F * h)), byte(64));
00136   drawLine(res, Point2D<int>(0, h-1), Point2D<int>(w-1, h-1), byte(64));
00137 
00138   float minii = mini, maxii = maxi;
00139   if (maxi == -1.0F) { minii = findMin(); maxii = findMax(); }
00140 
00141   // uniform histogram
00142   if (maxii == minii) minii = maxii - 1.0F;
00143 
00144   float range = maxii - minii;
00145 
00146   for (uint i = 0; i < itsHistogram.size(); i++)
00147     {
00148       int t = abs(h - int((itsHistogram[i] - minii) / range * float(h)));
00149 
00150       // if we have at least 1 pixel worth to draw
00151       if (t < h-1)
00152         {
00153           for (int j = 0; j < dw; j++)
00154             drawLine(res,
00155                      Point2D<int>(dw * i + j, t),
00156                      Point2D<int>(dw * i + j, h - 1),
00157                      byte(255));
00158           //drawRect(res, Rectangle::tlbrI(t,dw*i,h-1,dw*i+dw-1), byte(255));
00159         }
00160     }
00161 
00162   return res;
00163 }
00164 
00165 
00166 // #######################################################################
00167 float Histogram::getValue(const uint index) const
00168 {
00169   if (index < itsHistogram.size()) return itsHistogram[index];
00170   LFATAL("Index %d out of range [0..%"ZU"]",
00171          index, itsHistogram.size());
00172   return 0.0F;
00173 }
00174 
00175 // #######################################################################
00176 float Histogram::operator[](const uint index) const
00177 {
00178   ASSERT(index < itsHistogram.size());
00179   return itsHistogram[index];
00180 }
00181 
00182 // #######################################################################
00183 void Histogram::smooth()
00184 {
00185   std::vector<float> vect(itsHistogram.size());
00186   const uint siz = itsHistogram.size();
00187 
00188   for (uint n = 0 ; n < siz ; n++)
00189     {
00190       float val0 = itsHistogram[ (n-1+siz) % siz ];
00191       float val1 = itsHistogram[ (n  +siz) % siz ];
00192       float val2 = itsHistogram[ (n+1+siz) % siz ];
00193 
00194       vect[n] = 0.25F * (val0 + 2.0F*val1 + val2);
00195     }
00196 
00197   for (uint n = 0 ; n < siz ; n++) itsHistogram[n] = vect[n];
00198 }
00199 
00200 // #######################################################################
00201 void Histogram::smooth(Image<double> kernel)
00202 {
00203   ASSERT(kernel.getWidth() == 1 || kernel.getHeight() == 1);
00204   int ksize  = kernel.getSize();
00205   int hksize = ksize/2;
00206   
00207   int size = itsHistogram.size();
00208   std::vector<float> vect(size);
00209 
00210   // float fsumb = 0.0;
00211   // for (int i = 0; i < size; i++) 
00212   //   {
00213   //     fsumb+= itsHistogram[i];
00214   //   }
00215   //LINFO("ORG: fsumb: %f hksize: %d", fsumb, hksize);
00216 
00217   for (int i = 0; i < size; i++)
00218     {
00219       float total = 0.0; float tweight = 0.0;
00220       for (int j = -hksize; j <= hksize; j++)
00221         {
00222           int k = i+j; int l = j+hksize;
00223           if(k >= 0 && k < size)
00224             {
00225               float weight = kernel.getVal(l);
00226               total   += itsHistogram[k]*weight;
00227               tweight += weight;
00228             }
00229           vect[i] = total;///tweight;
00230         }
00231       //LINFO("v[%3d]= %15.5f == (%15.5f/%15.5f) = %15.5f", 
00232       //      i, itsHistogram[i], total, tweight, vect[i]);
00233     }
00234   for (int i = 0; i < size; i++) itsHistogram[i] = vect[i];
00235 
00236   // float fsuma = 0.0;  
00237   // for (int i = 0; i < size; i++) 
00238   //   {
00239   //     fsuma += itsHistogram[i];
00240   //   }
00241   //LINFO("SMO: fsuma: %f", fsuma);
00242 }
00243 
00244 // #######################################################################
00245 float Histogram::findMax() const
00246 {
00247   float maxi = itsHistogram[0];
00248   for (uint n = 1 ; n < itsHistogram.size() ; n++)
00249     if (itsHistogram[n] > maxi) maxi = itsHistogram[n];
00250   return maxi;
00251 }
00252 
00253 // #######################################################################
00254 void Histogram::findMax(int &max_loc, float &max_val)
00255 {
00256   max_val = itsHistogram[0];
00257   max_loc = 0;
00258 
00259   for (uint n = 1 ; n < itsHistogram.size() ; n++)
00260     if (itsHistogram[n] > max_val){
00261       max_val = itsHistogram[n];
00262       max_loc = n;
00263     }
00264 }
00265 
00266 // #######################################################################
00267 float Histogram::findMin() const
00268 {
00269   float mini = itsHistogram[0];
00270   for (uint n = 1 ; n < itsHistogram.size() ; n++)
00271     if (itsHistogram[n] < mini) mini = itsHistogram[n];
00272   return mini;
00273 }
00274 
00275 // #######################################################################
00276 void Histogram::findMinMax(double &min, double &max)
00277 {
00278   max = itsHistogram[0];
00279   min = max;
00280   for (uint n = 1 ; n < itsHistogram.size() ; n++)
00281   {
00282     if (itsHistogram[n] > max) max = itsHistogram[n];
00283     if (itsHistogram[n] < min) min = itsHistogram[n];
00284   }
00285 }
00286 
00287 
00288 // #######################################################################
00289 void Histogram::clear()
00290 {
00291   int size = itsHistogram.size();
00292   itsHistogram.clear();
00293   itsHistogram.resize(size, 0);
00294 }
00295 
00296 // #######################################################################
00297 void Histogram::resize(uint size)
00298 {
00299   itsHistogram.clear();
00300   itsHistogram.resize(size);
00301 }
00302 
00303 // #######################################################################
00304 int Histogram::getSize()
00305 {
00306   return itsHistogram.size();
00307 }
00308 
00309 uint Histogram::size() const
00310 {
00311   return itsHistogram.size();
00312 }
00313 
00314 // #######################################################################
00315 void Histogram::normalize(double sum)
00316 {
00317   if (sum == -1)
00318   {
00319     sum = 0;
00320     for(uint i=0; i<itsHistogram.size(); i++)
00321       sum += itsHistogram[i];
00322   }
00323 
00324   for(uint i=0; i<itsHistogram.size(); i++)
00325     itsHistogram[i] /= sum;
00326 }
00327 
00328 // #######################################################################
00329 double Histogram::getDistance(const Histogram& hist)
00330 {
00331   if (hist.size() > itsHistogram.size())
00332     LFATAL("Incomputable histograms");
00333   double sum = 0;
00334 
00335   for(uint i=0; i<itsHistogram.size(); i++)
00336   {
00337     //euclidean distance
00338     sum += fabs(itsHistogram[i]-hist[i]);
00339 
00340     //histogram intersection
00341     //sum += std::min(itsHistogram[i],hist[i]);
00342 
00343   }
00344 
00345   return sum;
00346 }
00347 
00348 // ######################################################################
00349 float Histogram::getChiSqDiff(Histogram hist2)
00350 {
00351   ASSERT(itsHistogram.size() == hist2.size());
00352 
00353   // Chi-square difference 
00354   float diff = 0.0;
00355   for(uint i = 0; i < hist2.size(); i++)
00356     {
00357       float dif = itsHistogram[i] - hist2[i];
00358       float sum = itsHistogram[i] + hist2[i];
00359       if(sum != 0.0F) diff += (dif*dif)/sum;
00360 
00361       // LINFO("[%3d] %15.5f  vs. %15.5f  ||| dif: %f sum: %f ---> %f", 
00362       //       i, itsHistogram[i], hist2[i], dif, sum, diff);
00363     }
00364   diff = diff/2.0;
00365 
00366   return diff;
00367 }
00368 
00369 // #######################################################################
00370 void Histogram::divide(float div)
00371 {
00372   for(uint i = 0; i < itsHistogram.size(); i++)
00373     {
00374       //LINFO("%f/%f", itsHistogram[i], div);
00375       itsHistogram[i] = itsHistogram[i]/div;
00376       //LINFO("= %f", itsHistogram[i]);
00377     }
00378 }
00379 
00380 // ######################################################################
00381 /* So things look consistent in everyone's emacs... */
00382 /* Local Variables: */
00383 /* indent-tabs-mode: nil */
00384 /* End: */
Generated on Sun May 8 08:42:16 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3