00001 /*!@file TestSuite/test-retinex.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/TestSuite/test-retinex.C $ 00035 // $Id: test-retinex.C 9997 2008-07-29 01:12:16Z icore $ 00036 // 00037 00038 #ifndef TESTSUITE_TEST_RETINEX_C_DEFINED 00039 #define TESTSUITE_TEST_RETINEX_C_DEFINED 00040 00041 #include "GUI/XWinManaged.H" 00042 #include "Image/ColorOps.H" 00043 #include "Image/CutPaste.H" 00044 #include "Image/Image.H" 00045 #include "Image/ImageSet.H" 00046 #include "Image/MathOps.H" 00047 #include "Image/Pixels.H" 00048 #include "Image/Range.H" 00049 #include "Image/Retinex.H" 00050 #include "Raster/PfmWriter.H" 00051 #include "Raster/GenericFrame.H" 00052 #include "Raster/Raster.H" 00053 #include "Util/Assert.H" 00054 #include "Util/Types.H" 00055 #include "Util/log.H" 00056 #include "Util/sformat.H" 00057 #include "rutz/time.h" 00058 00059 #include <fstream> 00060 #include <string> 00061 #include <unistd.h> 00062 00063 int main(int argc, char** argv) 00064 { 00065 MYLOGVERB=LOG_INFO; 00066 00067 if (argc < 2 || argc > 5) 00068 { 00069 LERROR("usage: %s imagefile ?do-xwindows? ?do-save? ?gamma?", argv[0]); 00070 return -1; 00071 } 00072 00073 const char* const fname = argv[1]; 00074 const bool interactive = argc > 2 && atoi(argv[2]) != 0; 00075 const bool dosave = argc > 3 && atoi(argv[3]) != 0; 00076 const float gam = argc > 4 ? atof(argv[4]) : 0.5; 00077 00078 const Image<PixRGB<float> > rgbf = Raster::ReadFrame(fname).asRgbF32(); 00079 Image<float> r, g, b; 00080 getComponents(rgbf, r, g, b); 00081 00082 XWinManaged* xwin = 0; 00083 if (interactive) 00084 { 00085 xwin = new XWinManaged(Image<PixRGB<byte> >(rgbf), "rgb"); 00086 00087 Image<float> r2 = toPower(r, gam); 00088 Image<float> g2 = toPower(g, gam); 00089 Image<float> b2 = toPower(b, gam); 00090 00091 inplaceNormalize(r2, 0.0f, 255.0f); 00092 inplaceNormalize(g2, 0.0f, 255.0f); 00093 inplaceNormalize(b2, 0.0f, 255.0f); 00094 00095 new XWinManaged(makeRGB(Image<byte>(r2), 00096 Image<byte>(g2), 00097 Image<byte>(b2)), 00098 "rgb^gamma"); 00099 00100 new XWinManaged(Image<byte>(r2), "r^gamma"); 00101 new XWinManaged(Image<byte>(g2), "g^gamma"); 00102 new XWinManaged(Image<byte>(b2), "b^gamma"); 00103 } 00104 00105 const int niter = 4; 00106 00107 const size_t depth = retinexDepth(rgbf.getDims()); 00108 00109 LINFO("depth = %"ZU, depth); 00110 00111 rutz::time t1 = rutz::time::rusage_now(); 00112 00113 // const Rectangle outrect(Point2D<int>(128,128), Dims(128,128)); 00114 const Rectangle outrect(Point2D<int>(0,0), rgbf.getDims()); 00115 00116 const ImageSet<float> RR = 00117 buildPyrRetinexLog<float>(log(r * 256.0F + 1.0F), depth, niter, outrect); 00118 const ImageSet<float> GG = 00119 buildPyrRetinexLog<float>(log(g * 256.0F + 1.0F), depth, niter, outrect); 00120 const ImageSet<float> BB = 00121 buildPyrRetinexLog<float>(log(b * 256.0F + 1.0F), depth, niter, outrect); 00122 00123 rutz::time t2 = rutz::time::rusage_now(); 00124 00125 LINFO("pyramid time = %.4fs", (t2 - t1).sec()); 00126 00127 for (size_t i = 0; i < RR.size(); ++i) 00128 { 00129 if (dosave) 00130 { 00131 PfmWriter::writeFloat(Image<float>(RR[i]), 00132 sformat("rlev%"ZU".pfm", i)); 00133 PfmWriter::writeFloat(Image<float>(GG[i]), 00134 sformat("glev%"ZU".pfm", i)); 00135 PfmWriter::writeFloat(Image<float>(BB[i]), 00136 sformat("blev%"ZU".pfm", i)); 00137 } 00138 00139 if (i == 0) 00140 { 00141 Range<float> rrng = rangeOf(RR[i]); 00142 Range<float> grng = rangeOf(GG[i]); 00143 Range<float> brng = rangeOf(BB[i]); 00144 00145 LINFO("rrng = %f .. %f", rrng.min(), rrng.max()); 00146 LINFO("grng = %f .. %f", grng.min(), grng.max()); 00147 LINFO("brng = %f .. %f", brng.min(), brng.max()); 00148 00149 Image<float> R = exp(RR[i]*gam); 00150 Image<float> G = exp(GG[i]*gam); 00151 Image<float> B = exp(BB[i]*gam); 00152 00153 inplaceNormalize(R, 0.0f, 255.0f); 00154 inplaceNormalize(G, 0.0f, 255.0f); 00155 inplaceNormalize(B, 0.0f, 255.0f); 00156 00157 if (interactive) 00158 { 00159 const Image<PixRGB<byte> > outrgb = 00160 makeRGB(Image<byte>(R), Image<byte>(G), Image<byte>(B)); 00161 00162 const Image<PixRGB<byte> > outrgbcrop = crop(outrgb, outrect); 00163 00164 new XWinManaged(outrgb, sformat("Retinex[%"ZU"]", i).c_str()); 00165 new XWinManaged(outrgbcrop, sformat("cropped Retinex[%"ZU"]", i).c_str()); 00166 new XWinManaged(Image<byte>(R), sformat("R[%"ZU"]", i).c_str()); 00167 new XWinManaged(Image<byte>(G), sformat("G[%"ZU"]", i).c_str()); 00168 new XWinManaged(Image<byte>(B), sformat("B[%"ZU"]", i).c_str()); 00169 } 00170 } 00171 } 00172 00173 while (xwin && !xwin->pressedCloseButton()) 00174 { 00175 usleep(20000); 00176 } 00177 } 00178 00179 // ###################################################################### 00180 /* So things look consistent in everyone's emacs... */ 00181 /* Local Variables: */ 00182 /* mode: c++ */ 00183 /* indent-tabs-mode: nil */ 00184 /* End: */ 00185 00186 #endif // TESTSUITE_TEST_RETINEX_C_DEFINED