00001 /*!@file MBARI/MbariFrameSeries.C Customized output frame series class 00002 for use in MbariResultViewer */ 00003 00004 // //////////////////////////////////////////////////////////////////// // 00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00006 // by the 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: 00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/MBARI/MbariFrameSeries.C $ 00036 // $Id: MbariFrameSeries.C 14376 2011-01-11 02:44:34Z pez $ 00037 // 00038 00039 #ifndef MBARI_MBARIFRAMESERIES_C_DEFINED 00040 #define MBARI_MBARIFRAMESERIES_C_DEFINED 00041 00042 #include "MBARI/MbariFrameSeries.H" 00043 00044 #include "Component/GlobalOpts.H" // for OPT_TestMode 00045 #include "Component/ModelOptionDef.H" 00046 #include "Component/OptionManager.H" 00047 #include "Image/CutPaste.H" // for inplaceEmbed() 00048 #include "Image/Image.H" 00049 #include "Image/Pixels.H" 00050 #include "Image/ShapeOps.H" // for rescale() 00051 #include "Media/MediaOpts.H" 00052 #include "Raster/Raster.H" 00053 #include "Transport/RasterInputSeries.H" 00054 #include "Transport/TransportOpts.H" // for OPT_OutputRasterFileFormat 00055 #include "Util/FileUtil.H" // for splitPath() 00056 #include "Util/TextLog.H" 00057 #include "Util/log.H" 00058 #include "Util/sformat.H" 00059 00060 #include <cstdio> 00061 00062 // maximum number of displays we cando before giving up 00063 #define MAXDISP 20 00064 00065 const ModelOptionCateg MOC_MBARIRV = { 00066 MOC_SORTPRI_4, "MBARI Result Viewer Related Options" }; 00067 00068 // Used by: InputMbariFrameSeries 00069 static const ModelOptionDef OPT_InputMbariPreserveAspect = 00070 { MODOPT_FLAG, "InputMbariPreserveAspect", &MOC_MBARIRV, OPTEXP_MRV, 00071 "Preserve input frame aspect ratio if rescaling to fixed dims", 00072 "mbari-preserve-input-aspect", '\0', "", "false" }; 00073 00074 // Used by: OutputMbariFrameSeries 00075 static const ModelOptionDef OPT_OutputMbariShowFrames = 00076 { MODOPT_FLAG, "OutputMbariShowFrames", &MOC_MBARIRV, OPTEXP_MRV, 00077 "Show output frames", 00078 "mbari-display-output-frames", '\0', "", "true" }; 00079 00080 // ###################################################################### 00081 // #################### InputMbariFrameSeries 00082 // ###################################################################### 00083 00084 InputMbariFrameSeries::InputMbariFrameSeries(OptionManager& mgr, 00085 const std::string& descrName, 00086 const std::string& tag) : 00087 ModelComponent(mgr, "Input "+descrName, "Input"+tag), 00088 itsDims(&OPT_InputFrameDims, this), 00089 itsPreserveAspect(&OPT_InputMbariPreserveAspect, this), 00090 itsRasterFileFormat(&OPT_InputRasterFileFormat, this), 00091 itsStem("") 00092 {} 00093 00094 // ###################################################################### 00095 InputMbariFrameSeries::~InputMbariFrameSeries() 00096 {} 00097 00098 // ###################################################################### 00099 Dims InputMbariFrameSeries::peekDims(const int fnum) 00100 { 00101 // if we are doing resizing, our dims are the resized dims: 00102 if (itsDims.getVal().w() != 0 && itsDims.getVal().h() != 0) 00103 return itsDims.getVal(); 00104 00105 return Raster::getImageDims(sformat("%s%06d", itsStem.c_str(), fnum), 00106 itsRasterFileFormat.getVal()); 00107 } 00108 00109 // ###################################################################### 00110 Image<PixRGB<byte> > InputMbariFrameSeries::readRGB(const int fnum) 00111 { 00112 const Image< PixRGB<byte> > ima = 00113 Raster::ReadRGB(sformat("%s%06d", itsStem.c_str(), fnum), 00114 itsRasterFileFormat.getVal()); 00115 00116 if (itsDims.getVal().isEmpty()) 00117 return ima; 00118 00119 if (itsPreserveAspect.getVal()) 00120 { 00121 Image<PixRGB<byte> > res(itsDims.getVal(), ZEROS); 00122 PixRGB<byte> bg = PixRGB<byte>(64, 64, 64); 00123 inplaceEmbed(res, ima, res.getBounds(), bg, true); 00124 return res; 00125 } 00126 00127 return rescale(ima, itsDims.getVal()); 00128 } 00129 00130 // ###################################################################### 00131 void InputMbariFrameSeries::setFileStem(const std::string& stem) 00132 { 00133 itsStem = stem; 00134 } 00135 00136 // ###################################################################### 00137 // #################### OutputMbariFrameSeries 00138 // ###################################################################### 00139 OutputMbariFrameSeries::OutputMbariFrameSeries(OptionManager& mgr) 00140 : 00141 ModelComponent(mgr, "Output MBARI Frame Series", 00142 "OutputMbariFrameSeries"), 00143 itsLogFile(&OPT_TextLogFile, this), 00144 itsTestMode(&OPT_TestMode, this), 00145 itsDims(&OPT_OutputFrameDims, this), 00146 itsPreserveAspect(&OPT_OutputPreserveAspect, this), 00147 itsShowFrames(&OPT_OutputMbariShowFrames, this), 00148 itsRasterFileFormat(&OPT_OutputRasterFileFormat, this), 00149 itsStem(""), 00150 itsDidDisplay(0) 00151 { } 00152 00153 // ###################################################################### 00154 OutputMbariFrameSeries::~OutputMbariFrameSeries() 00155 { } 00156 00157 // ###################################################################### 00158 void OutputMbariFrameSeries::setFileStem(const std::string& stem) 00159 { 00160 if (started()) 00161 LFATAL("Cannot change file stem while started"); 00162 itsStem = stem; 00163 } 00164 00165 // ###################################################################### 00166 std::string OutputMbariFrameSeries::getFileStem() const 00167 { return itsStem; } 00168 00169 // ###################################################################### 00170 void OutputMbariFrameSeries:: 00171 writeMbariRGB(const Image< PixRGB<byte> >& image, 00172 const std::string& otherstem, 00173 const int framenum) 00174 { 00175 // figure out the file name to use: 00176 std::string fname(computeFileName(framenum, otherstem)); 00177 00178 // find out file format: 00179 const RasterFileFormat ff = itsRasterFileFormat.getVal(); 00180 00181 // resize the image as appropriate: 00182 Image< PixRGB<byte> > ima = OutputMbariFrameSeries::doResizeImage(image); 00183 00184 // write the image: 00185 fname = Raster::WriteRGB(ima, fname, ff); 00186 textLog(itsLogFile.getVal(), "WriteRGB", fname); 00187 00188 // do we want to show the image? 00189 if (okToDisplay()) 00190 Raster::Display(fname.c_str()); 00191 } 00192 00193 // ###################################################################### 00194 void OutputMbariFrameSeries:: 00195 writeMbariGray(const Image<byte>& image, 00196 const std::string& otherstem, 00197 const int framenum) 00198 { 00199 // figure out the file name to use: 00200 std::string fname(computeFileName(framenum, otherstem)); 00201 00202 // find out file format: 00203 const RasterFileFormat ff = itsRasterFileFormat.getVal(); 00204 00205 // resize the image as appropriate: 00206 Image<byte> ima = OutputMbariFrameSeries::doResizeImage(image); 00207 00208 // write the image: 00209 fname = Raster::WriteGray(ima, fname, ff); 00210 textLog(itsLogFile.getVal(), "WriteGray", fname); 00211 00212 // do we want to show the image? do it only if we are not in test mode 00213 if (okToDisplay()) 00214 Raster::Display(fname.c_str()); 00215 } 00216 00217 // ###################################################################### 00218 void OutputMbariFrameSeries:: 00219 writeMbariFloat(const Image<float>& image, 00220 const std::string& otherstem, 00221 int flags, 00222 const int framenum) 00223 { 00224 // figure out the file name to use: 00225 std::string fname(computeFileName(framenum, otherstem)); 00226 00227 // find out file format: 00228 RasterFileFormat ff = itsRasterFileFormat.getVal(); 00229 00230 // resize the image as appropriate: 00231 Image<float> ima = OutputMbariFrameSeries::doResizeImage(image); 00232 00233 // do special handling for FLOAT_NORM_PRESERVE -- in that case, we 00234 // want to turn off FLOAT_NORM_0_255, and save the image in 00235 // RASFMT_PFM format: 00236 if (flags & FLOAT_NORM_PRESERVE) 00237 { 00238 flags &= ~FLOAT_NORM_0_255; 00239 ff = RASFMT_PFM; 00240 } 00241 00242 // write the image: 00243 fname = Raster::WriteFloat(ima, flags, fname, ff); 00244 textLog(itsLogFile.getVal(), "WriteFloat", fname); 00245 00246 // do we want to show the image? do it only if we are not in test mode 00247 if (okToDisplay()) 00248 Raster::Display(fname.c_str()); 00249 } 00250 00251 // ###################################################################### 00252 std::string OutputMbariFrameSeries:: 00253 computeFileName(const int framenum, const std::string& otherstem) const 00254 { 00255 // first split itsStem into path and file components: 00256 std::string path, file; 00257 splitPath(itsStem, path, file); 00258 00259 // use an alternate stem 00260 std::string otherpath, otherfile; 00261 splitPath(otherstem, otherpath, otherfile); 00262 00263 return sformat("%s%s%06d", path.c_str(), otherfile.c_str(), framenum); 00264 } 00265 00266 // ###################################################################### 00267 template <class T> 00268 Image<T> OutputMbariFrameSeries::doResizeImage(const Image<T>& input) const 00269 { 00270 if (itsDims.getVal().isEmpty()) return input; 00271 if (itsPreserveAspect.getVal()) 00272 { 00273 Image<T> res(itsDims.getVal(), ZEROS); 00274 T bg = T(); bg += 64; 00275 inplaceEmbed(res, input, res.getBounds(), bg, true); 00276 return res; 00277 } 00278 return rescale(input, itsDims.getVal()); 00279 } 00280 00281 // ###################################################################### 00282 bool OutputMbariFrameSeries::okToDisplay() 00283 { 00284 if (itsTestMode.getVal() == false && itsShowFrames.getVal()) 00285 { 00286 ++ itsDidDisplay; 00287 if (itsDidDisplay > MAXDISP) 00288 LERROR("**** TOO MANY WINDOWS! NOT DISPLAYING IMAGE..."); 00289 else 00290 return true; 00291 } 00292 return false; 00293 // itsDidDisplay is reset to zero at each update() 00294 } 00295 00296 // ###################################################################### 00297 /* So things look consistent in everyone's emacs... */ 00298 /* Local Variables: */ 00299 /* indent-tabs-mode: nil */ 00300 /* End: */ 00301 00302 #endif // MBARI_MBARIFRAMESERIES_C_DEFINED