contrib/mul/ipts/ipts_local_entropy.cxx
Go to the documentation of this file.
00001 // This is mul/ipts/ipts_local_entropy.cxx
00002 #include "ipts_local_entropy.h"
00003 //:
00004 // \file
00005 // \brief Compute entropy in region around each image pixel
00006 // \author Tim Cootes
00007 
00008 #include <vcl_vector.h>
00009 #include <vcl_cmath.h>
00010 #include <vcl_cassert.h>
00011 
00012 inline double histo_entropy_sum(const vcl_vector<int>& histo,
00013                                 unsigned min_v, unsigned max_v)
00014 {
00015   double sum = 0.0;
00016   for (unsigned k=min_v;k<=max_v;++k)
00017     if (histo[k]>0) sum+=histo[k]*vcl_log(double(histo[k]));
00018   return sum;
00019 }
00020 
00021 //: Compute local entropy in square region around each pixel in image
00022 //  For each pixel in image, compute entropy in region (2h+1)x(2h+1)
00023 //  centred on the pixel.  Result put in entropy image, which is of
00024 //  size (image.ni()-2h) x (image.nj()-2h). Thus entropy(i,j)
00025 //  corresponds to the value in the box around image point (i+h,j+h).
00026 //
00027 //  Values in image are assumed to lie in the range [min_v,max_v].
00028 //  Any values outside that range will be ignored in the entropy calculation.
00029 void ipts_local_entropy(const vil_image_view<vxl_byte>& image,
00030                         vil_image_view<float>& entropy,
00031                         unsigned h, unsigned min_v, unsigned max_v)
00032 {
00033   vcl_vector<int> histo(256);
00034   const unsigned ni=image.ni(),nj=image.nj();
00035   assert(image.nplanes()==1 && ni>2*h && nj>2*h);
00036   unsigned eni = ni-2*h, enj=nj-2*h;
00037   entropy.set_size(eni,enj);
00038 
00039   unsigned h2 = 2*h+1;
00040   unsigned n = h2*h2;
00041   double logn = vcl_log(double(n));
00042 
00043   const vcl_ptrdiff_t istep=image.istep(),   jstep=image.jstep();
00044 //const vcl_ptrdiff_t eistep=entropy.istep(),ejstep=entropy.jstep();
00045 
00046   for (unsigned i=0;i<eni;++i)
00047   {
00048     const vxl_byte* im = &image(i,0);
00049 
00050     // Create histogram from h2 x h2 region starting at (i,0)
00051     for (unsigned k=min_v;k<=max_v;++k) histo[k]=0;
00052     for (unsigned j1=0;j1<h2;++j1, im+=jstep)
00053     {
00054       const vxl_byte* p = im;
00055       for (unsigned i1=0;i1<h2;++i1,p+=istep) histo[*p]++;
00056     }
00057       // Compute (negative) entropy of histogram (sum plog(p))
00058     entropy(i,0) = float(logn-histo_entropy_sum(histo,min_v,max_v)/n);
00059 
00060     for (unsigned j=1;j<enj;++j)
00061     {
00062       // Update the histogram
00063       // Remove previous line
00064       const vxl_byte* p = &image(i,j-1);
00065       for (unsigned i1=0;i1<h2;++i1,p+=istep) histo[*p]--;
00066       // Add line at end
00067       p = &image(i,j+h2-1);
00068       for (unsigned i1=0;i1<h2;++i1,p+=istep) histo[*p]++;
00069 
00070        // Compute entropy of histogram (sum plog(p))
00071       entropy(i,j) = float(logn-histo_entropy_sum(histo,min_v,max_v)/n);  // Negative entropy
00072     }
00073   }
00074 }