DpxParser.C

Go to the documentation of this file.
00001 /*!@file Raster/DpxParser.C */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00005 // by the 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: Rob Peters <rjpeters at usc dot edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Raster/DpxParser.C $
00035 // $Id: DpxParser.C 9229 2008-02-07 02:31:25Z rjpeters $
00036 //
00037 
00038 #ifndef RASTER_DPXPARSER_C_DEFINED
00039 #define RASTER_DPXPARSER_C_DEFINED
00040 
00041 #include "Raster/DpxParser.H"
00042 
00043 #include "Image/Image.H"
00044 #include "Image/MathOps.H"
00045 #include "Image/Pixels.H"
00046 #include "Image/Range.H"
00047 #include "Raster/DpxFile.H"
00048 #include "Raster/GenericFrame.H"
00049 
00050 #include <vector>
00051 
00052 namespace
00053 {
00054   Image<PixRGB<float> > deBayer(const Image<float>& bayer)
00055   {
00056     Image<PixRGB<float> > result(bayer.getDims(), NO_INIT);
00057 
00058     const int w = bayer.getWidth();
00059     const int h = bayer.getHeight();
00060 
00061     ASSERT(w % 2 == 0);
00062     ASSERT(h % 2 == 0);
00063 
00064     Image<float>::const_iterator sptr = bayer.begin();
00065     Image<PixRGB<float> >::iterator dptr = result.beginw();
00066 
00067     for (int y = 0; y < h; y += 2)
00068       {
00069         for (int x = 0; x < w; x += 2)
00070           {
00071             if (x < 2 || x >= w-2 || y < 2 || y >= h-2)
00072               {
00073                 const float r = sptr[0];
00074                 const float g = 0.5f * (sptr[1] + sptr[w]);
00075                 const float b = sptr[w+1];
00076 
00077                 dptr[0].p[0] = r;
00078                 dptr[1].p[0] = r;
00079                 dptr[w].p[0] = r;
00080                 dptr[w+1].p[0] = r;
00081 
00082                 dptr[0].p[1] = g;
00083                 dptr[1].p[1] = g;
00084                 dptr[w].p[1] = g;
00085                 dptr[w+1].p[1] = g;
00086 
00087                 dptr[0].p[2] = b;
00088                 dptr[1].p[2] = b;
00089                 dptr[w].p[2] = b;
00090                 dptr[w+1].p[2] = b;
00091               }
00092             else
00093               {
00094                 /*
00095 
00096                   +------+------+------+------+
00097                   :-w-1  :-w    :-w+1  :-w+2  :
00098                   :      :      :      :      :
00099                   :    B :    G :    B :    G :
00100                   +------+======+======+------+
00101                   :-1    |0     |1     |2     :
00102                   :      |      |      |      :
00103                   :    G |    R |    G |    R :
00104                   +------+======+======+------+
00105                   :w-1   |w     |w+1   |w+2   :
00106                   :      |      |      |      :
00107                   :    B |    G |    B |    G :
00108                   +------+======+======+------+
00109                   :w*2-1 :w*2   :w*2+1 :w*2+2 :
00110                   :      :      :      :      :
00111                   :    G :    R :    G :    R :
00112                   +------+------+------+------+
00113 
00114                 */
00115 
00116                 dptr[0].p[0] = sptr[0];
00117                 dptr[1].p[0] = 0.5f * (sptr[0] + sptr[2]);
00118                 dptr[w].p[0] = 0.5f * (sptr[0] + sptr[w*2]);
00119                 dptr[w+1].p[0] = 0.25f * (sptr[0] + sptr[2] + sptr[w*2] + sptr[w*2+2]);
00120 
00121                 dptr[0].p[1] = 0.25f * (sptr[-w] + sptr[-1] + sptr[1] + sptr[w]);
00122                 dptr[1].p[1] = 0.5f * sptr[1] + 0.125f * (sptr[-w] + sptr[-w+2] + sptr[w] + sptr[w+2]);
00123                 dptr[w].p[1] = 0.5f * sptr[w] + 0.125f * (sptr[-1] + sptr[1] + sptr[w*2-1] + sptr[w*2+1]);
00124                 dptr[w+1].p[1] = 0.25f * (sptr[1] + sptr[w] + sptr[w+2] + sptr[w*2+1]);
00125 
00126                 dptr[0].p[2] = 0.25f * (sptr[-w-1] + sptr[-w+1] + sptr[w-1] + sptr[w+1]);
00127                 dptr[1].p[2] = 0.5f * (sptr[w+1] + sptr[-w+1]);
00128                 dptr[w].p[2] = 0.5f * (sptr[w+1] + sptr[w-1]);
00129                 dptr[w+1].p[2] = sptr[w+1];
00130               }
00131 
00132             sptr += 2;
00133             dptr += 2;
00134           }
00135 
00136         sptr += w;
00137         dptr += w;
00138       }
00139 
00140     return result;
00141   }
00142 
00143   void showStats(const Image<uint16>& img, float sclip_lo, float sclip_hi)
00144   {
00145     const int w = img.getWidth();
00146     const int h = img.getHeight();
00147 
00148     const int w1 = w/4;
00149     const int w2 = (w*3)/4;
00150     const int h1 = h/4;
00151     const int h2 = (h*3)/4;
00152 
00153     const uint16* sptr = img.getArrayPtr();
00154     Range<uint16> srng;
00155     Range<uint16> srng_center;
00156 
00157     int total_lo_clips = 0;
00158     int total_hi_clips = 0;
00159     int center_lo_clips = 0;
00160     int center_hi_clips = 0;
00161 
00162     for (int y = 0; y < h; ++y)
00163       for (int x = 0; x < w; ++x)
00164         {
00165           if (*sptr < sclip_lo)
00166             ++total_lo_clips;
00167           else if (*sptr > sclip_hi)
00168             ++total_hi_clips;
00169 
00170           srng.merge(*sptr);
00171           if (x >= w1 && x < w2 && y >= h1 && y < h2)
00172             {
00173               srng_center.merge(*sptr);
00174               if (*sptr < sclip_lo)
00175                 ++center_lo_clips;
00176               else if (*sptr > sclip_hi)
00177                 ++center_hi_clips;
00178             }
00179           ++sptr;
00180         }
00181 
00182     LINFO("srng = %u .. %u, srng[center] = %u .. %u, sclip_lo = %g [%g%%, %g%%], sclip_hi = %g [%g%%, %g%%]",
00183           srng.min(), srng.max(),
00184           srng_center.min(), srng_center.max(),
00185           sclip_lo, (100.0 * total_lo_clips) / (w*h), (100.0 * center_lo_clips) / (w*h/4),
00186           sclip_hi, (100.0 * total_hi_clips) / (w*h), (100.0 * center_hi_clips) / (w*h/4));
00187   }
00188 
00189   class ColorTable
00190   {
00191   public:
00192     ColorTable() {}
00193 
00194     void init(const size_t size,
00195               const float gamma,
00196               const bool do_log,
00197               const float sigm_contrast,
00198               const float sigm_thresh,
00199               const float sclip_lo,
00200               const float sclip_hi)
00201     {
00202       this->tab.resize(size);
00203 
00204       const float cmin = do_log ? logf(sclip_lo > 0.0f ? sclip_lo : 1.0f) : sclip_lo;
00205       const float crng = (do_log ? logf(sclip_hi) : sclip_hi) - cmin;
00206 
00207       const float sigmin = 1.0f / (1.0f + expf(sigm_contrast * sigm_thresh));
00208       const float sigrng = 1.0f / (1.0f + expf(sigm_contrast * (sigm_thresh-1.0f)))
00209         - sigmin;
00210 
00211       for (size_t i = 0; i < size; ++i)
00212         {
00213           float val = i;
00214           if (val < sclip_lo) val = sclip_lo;
00215           else if (val > sclip_hi) val = sclip_hi;
00216 
00217           if (do_log)
00218             val = logf(val > 0.0f ? val : 1.0f);
00219 
00220           val = (val - cmin) / crng;
00221 
00222           if (sigm_contrast != 0.0f)
00223             {
00224               val = 1.0f / (1.0f + expf(sigm_contrast * (sigm_thresh - val)));
00225               val = (val - sigmin) / sigrng;
00226             }
00227 
00228           val = 255.0f * powf(val, gamma);
00229 
00230           this->tab[i] = val;
00231         }
00232     }
00233 
00234     std::vector<float> tab;
00235   };
00236 
00237   float defaultGamma = 0.6f;
00238   float defaultSigmoidContrast = 10.0f;
00239   float defaultSigmoidThreshold = 0.1f;
00240   float defaultSrcClipLo = 0.0f;
00241   float defaultSrcClipHi = 5351.0f;
00242 }
00243 
00244 // ######################################################################
00245 void DpxParser::setDefaultGamma(float val)            { defaultGamma = val; }
00246 void DpxParser::setDefaultSigmoidContrast(float val)  { defaultSigmoidContrast = val; }
00247 void DpxParser::setDefaultSigmoidThreshold(float val) { defaultSigmoidThreshold = val; }
00248 void DpxParser::setDefaultSrcClipLo(float val)        { defaultSrcClipLo = val; }
00249 void DpxParser::setDefaultSrcClipHi(float val)        { defaultSrcClipHi = val; }
00250 
00251 // ######################################################################
00252 DpxParser::DpxParser(const char* filename)
00253   :
00254   dpx(new DpxFile(filename)),
00255   itsGamma(defaultGamma),
00256   itsDoLog(false),
00257   itsSigmoidContrast(defaultSigmoidContrast),
00258   itsSigmoidThresh(defaultSigmoidThreshold),
00259   itsSclipLo(defaultSrcClipLo),
00260   itsSclipHi(defaultSrcClipHi)
00261 {}
00262 
00263 // ######################################################################
00264 DpxParser::DpxParser(const char* filename,
00265                      float gamma,
00266                      bool do_log,
00267                      float sigm_contrast,
00268                      float sigm_thresh,
00269                      float sclip_lo,
00270                      float sclip_hi)
00271   :
00272   dpx(new DpxFile(filename)),
00273   itsGamma(gamma),
00274   itsDoLog(do_log),
00275   itsSigmoidContrast(sigm_contrast),
00276   itsSigmoidThresh(sigm_thresh),
00277   itsSclipLo(sclip_lo),
00278   itsSclipHi(sclip_hi)
00279 {}
00280 
00281 // ######################################################################
00282 DpxParser::~DpxParser()
00283 {
00284   delete dpx;
00285 }
00286 
00287 // ######################################################################
00288 GenericFrameSpec DpxParser::getFrameSpec() const
00289 {
00290   GenericFrameSpec result;
00291 
00292   result.nativeType = GenericFrame::RGB_F32;
00293   result.videoFormat = VIDFMT_AUTO;
00294   result.videoByteSwap = false;
00295   result.dims = dpx->dims;
00296   result.floatFlags = 0;
00297 
00298   return result;
00299 }
00300 
00301 // ######################################################################
00302 std::string DpxParser::getComments() const
00303 {
00304   return std::string();
00305 }
00306 
00307 // ######################################################################
00308 uint DpxParser::getTagCount() const
00309 {
00310   return 0;
00311 }
00312 
00313 // ######################################################################
00314 bool DpxParser::getTag(uint tag, std::string& name, std::string& value) const
00315 {
00316   return false;
00317 }
00318 
00319 // ######################################################################
00320 GenericFrame DpxParser::getFrame()
00321 {
00322   ASSERT(dpx->ih.ImageElement[0].BitSize == 16);
00323   ASSERT(dpx->ih.ImageElement[0].EndOfLinePadding == 0xFFFF);
00324 
00325   showStats(dpx->rawimage, itsSclipLo, itsSclipHi);
00326 
00327   ColorTable ctab;
00328   ctab.init(1<<16, itsGamma, itsDoLog,
00329             itsSigmoidContrast, itsSigmoidThresh,
00330             itsSclipLo, itsSclipHi);
00331 
00332   Image<float> fresult(dpx->dims, NO_INIT);
00333 
00334   const uint16* sptr = dpx->rawimage.getArrayPtr();
00335   for (Image<float>::iterator fptr = fresult.beginw(),
00336          stop = fresult.endw(); fptr != stop; ++fptr, ++sptr)
00337     {
00338       *fptr = ctab.tab[*sptr];
00339     }
00340 
00341   const Image<PixRGB<float> > cimg = deBayer(fresult);
00342 
00343   return GenericFrame(cimg, /* flags = */ 0);
00344 }
00345 
00346 // ######################################################################
00347 /* So things look consistent in everyone's emacs... */
00348 /* Local Variables: */
00349 /* mode: c++ */
00350 /* indent-tabs-mode: nil */
00351 /* End: */
00352 
00353 #endif // RASTER_DPXPARSER_C_DEFINED
Generated on Sun May 8 08:41:16 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3