00001 /*!@file ModelNeuron/StructurePlot.H Class declaration for StructurePlot 00002 which creates hierarchical 2d image represenation of a structures 00003 activity*/ 00004 00005 // //////////////////////////////////////////////////////////////////// // 00006 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00007 // University of Southern California (USC) and the iLab at USC. // 00008 // See http://iLab.usc.edu for information about this project. // 00009 // //////////////////////////////////////////////////////////////////// // 00010 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00011 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00012 // in Visual Environments, and Applications'' by Christof Koch and // 00013 // Laurent Itti, California Institute of Technology, 2001 (patent // 00014 // pending; application number 09/912,225 filed July 23, 2001; see // 00015 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00016 // //////////////////////////////////////////////////////////////////// // 00017 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00018 // // 00019 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00020 // redistribute it and/or modify it under the terms of the GNU General // 00021 // Public License as published by the Free Software Foundation; either // 00022 // version 2 of the License, or (at your option) any later version. // 00023 // // 00024 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00025 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00026 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00027 // PURPOSE. See the GNU General Public License for more details. // 00028 // // 00029 // You should have received a copy of the GNU General Public License // 00030 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00031 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00032 // Boston, MA 02111-1307 USA. // 00033 // //////////////////////////////////////////////////////////////////// // 00034 // 00035 // Primary maintainer for this file: David J. Berg <dberg@usc.edu> 00036 // $HeadURL:svn://ilab.usc.edu/trunk/saliency/src/ModelNeuron/StructurePlot.H$ 00037 00038 #ifndef MODELNEURON_STRUCTUREPLOT_H_DEFINED 00039 #define MODELNEURON_STRUCTUREPLOT_H_DEFINED 00040 00041 #include "Image/Layout.H" 00042 #include "Image/Image.H" 00043 #include "Image/Pixels.H" 00044 #include "Image/DrawOps.H" 00045 #include "Image/ShapeOps.H" 00046 #include "Image/ColorMap.H" 00047 #include "Image/ColorOps.H" 00048 #include "Image/MathOps.H" 00049 #include "Image/Range.H" 00050 #include "Util/StringConversions.H" 00051 00052 #include "ModelNeuron/LayerDecoder.H" 00053 #include "ModelNeuron/Location.H" 00054 #include "ModelNeuron/PlotBuffer.H" 00055 00056 class SimStructure; 00057 // ###################################################################### 00058 // ! A class for displaying a hierarchy of activity from a 00059 // SimStructure's sub units. 00060 // ###################################################################### 00061 enum NormalizeType {SCALE = 0, RANGE = 1, SET_RANGE = 2}; 00062 00063 class StructurePlot 00064 { 00065 public: 00066 //!Constructor 00067 StructurePlot(const SimStructure& structure, 00068 const NeuralDecoder& decoder, 00069 const uint depth = 2, 00070 const NormalizeType normtype = SCALE, 00071 const double& rangemin = 0, const double& rangemax = 0); 00072 00073 //!Constructor 00074 StructurePlot(const SimStructure& structure, 00075 const uint depth = 2, 00076 const NormalizeType normtype = SCALE, 00077 const double& rangemin = 0, const double& rangemax = 0); 00078 00079 //!Destructor 00080 ~StructurePlot(); 00081 00082 //!plot the structure 00083 Layout<PixRGB<byte> > draw(SimStructure& structure, //the structure to draw 00084 const uint w = 320, const uint h = 240, //the output width 00085 const Dims dims = Dims(0,1), //(1,0) for column, 0,1 for row plot 00086 const uint length = 250, //length in samples 00087 const uint plotdepth = 4, //depth in structure 00088 const bool usedisplayoutput = false); //use computation, or display 00089 00090 //!set the probe 00091 void setProbe(const Location& probe); 00092 00093 //!set the sampling rate of the plotter so that time plots can be 00094 //!labeled correctly 00095 void setSamplingRate(const SimTime& samplingrate); 00096 00097 //reset to state after construction; 00098 void reset(); 00099 00100 private: 00101 //!get the total number of subs 00102 uint countSubs(const SimStructure& structure, uint depth); 00103 00104 //!plot the structures 2d components 00105 Layout<PixRGB<byte> > drawStructure(SimStructure& structure, 00106 const uint w, const uint h, 00107 const uint depth, 00108 const bool usedisplayoutput); 00109 00110 //!prohibit copy constructor and assignment 00111 StructurePlot(const StructurePlot& rhs); 00112 StructurePlot& operator=(const StructurePlot& rhs); 00113 00114 NormalizeType itsNormType; 00115 std::vector<Range<double> > itsRange; 00116 std::vector<std::string> itsNames; 00117 std::vector<ColorMap> itsCol; 00118 int itsTotal, itsCount; 00119 std::vector<LayerDecoder> itsDecoder; 00120 Location itsProbe; 00121 PlotBufferList itsN; 00122 uint itsDepth; 00123 }; 00124 00125 // ###################################################################### 00126 // ! inline implementation for StructurePlot 00127 // ###################################################################### 00128 inline 00129 StructurePlot::StructurePlot(const SimStructure& structure, 00130 const NeuralDecoder& decoder, 00131 const uint depth, 00132 const NormalizeType normtype, 00133 const double& rangemin, const double& rangemax) : 00134 itsNormType(normtype), itsRange(), 00135 itsNames(), itsCol(), itsTotal(countSubs(structure, depth)), itsCount(-1), 00136 itsDecoder(), itsProbe(), itsN(), itsDepth(depth) 00137 { 00138 for (int ii = 0; ii < itsTotal; ++ii) 00139 { 00140 itsDecoder.push_back(LayerDecoder(decoder, structure.getOutDims())); 00141 itsRange.push_back(Range<double>(rangemin, rangemax)); 00142 } 00143 } 00144 00145 // ###################################################################### 00146 inline 00147 StructurePlot::StructurePlot(const SimStructure& structure, 00148 const uint depth, 00149 const NormalizeType normtype, 00150 const double& rangemin, const double& rangemax) : 00151 itsNormType(normtype), itsRange(), 00152 itsNames(), itsCol(), itsTotal(countSubs(structure, depth)), itsCount(-1), 00153 itsDecoder(), itsProbe(), itsN(), itsDepth(depth) 00154 { 00155 for (int ii = 0; ii < itsTotal; ++ii) 00156 itsRange.push_back(Range<double>(rangemin, rangemax)); 00157 } 00158 00159 // ###################################################################### 00160 inline 00161 StructurePlot::~StructurePlot() 00162 { } 00163 00164 // ###################################################################### 00165 void StructurePlot::setProbe(const Location& probe) 00166 { 00167 itsN.clear(); 00168 itsProbe = probe; 00169 }; 00170 00171 // ###################################################################### 00172 inline 00173 void StructurePlot::setSamplingRate(const SimTime& samplingrate) 00174 { 00175 itsN.setSamplingRate(samplingrate); 00176 } 00177 00178 // ###################################################################### 00179 inline 00180 Layout<PixRGB<byte> > 00181 StructurePlot::draw(SimStructure& structure, 00182 const uint w, const uint h, const Dims dims, 00183 const uint length, const uint plotdepth, 00184 const bool usedispout) 00185 { 00186 Layout<PixRGB<byte> > out; 00187 Layout<PixRGB<byte> > ds = drawStructure(structure, w, h, itsDepth, usedispout); 00188 //if we have a probe collect that info 00189 if (itsProbe.size() > 0) 00190 { 00191 std::vector<const SimUnit*> units; 00192 structure.getSimUnit(itsProbe, units); 00193 itsN.push(units, length, plotdepth, usedispout); 00194 out = itsN.draw(false, w*2, ds.getHeight(), dims, 00195 (itsNormType == SCALE) ? Range<double>(0.0, 0.0) : itsRange.back()); 00196 } 00197 //compine the probe and layer plots. 00198 out = hcat(ds, out); 00199 return out; 00200 } 00201 00202 // ###################################################################### 00203 inline 00204 Layout<PixRGB<byte> > 00205 StructurePlot::drawStructure(SimStructure& structure, 00206 const uint w, const uint h, 00207 const uint depth, const bool usedispout) 00208 { 00209 Layout<PixRGB<byte> > layout; 00210 00211 //perform depth first grab of output data 00212 if (depth > 0) 00213 for (uint i = 0; i < structure.numSubs(); ++i) 00214 { 00215 SimStructure& temp = structure.editSub(i); 00216 uint mydepth = depth - 1; 00217 layout = vcat(layout, drawStructure(temp, w, h, mydepth, usedispout)); 00218 } 00219 00220 //base case 00221 ++itsCount; 00222 00223 //since output is typically one of the subs in a structure, don't plot if we have children, unless we are at our 00224 //plotting depth 00225 if ((structure.numSubs() <= 0) || (depth == 0)) 00226 { 00227 Image<double> out = (usedispout) ? structure.getDisplayOutput() : structure.getOutput(); 00228 00229 if (itsDecoder.size() > 0) 00230 { 00231 itsDecoder[itsCount].push(out); 00232 out = itsDecoder[itsCount].getOutput(); 00233 } 00234 00235 //scale and convert type, rescale if necessary 00236 Image<byte> outb; 00237 if (itsNormType == SCALE) { 00238 inplaceNormalize(out, 0.0, 255.0); 00239 outb = out; 00240 } 00241 else if (itsNormType == RANGE) { 00242 itsRange[itsCount].merge(rangeOf(out)); 00243 outb = remapRange(out, itsRange[itsCount], Range<double>(0.0, 255.0)); 00244 } 00245 else if (itsNormType == SET_RANGE) 00246 outb = remapRange(out, itsRange[itsCount], Range<double>(0.0, 255.0)); 00247 00248 outb = rescale(outb, Dims(w,h)); 00249 00250 //add some text 00251 if ((itsNormType == RANGE) || (itsNormType == SET_RANGE)) 00252 { 00253 std::string temp = itsNames[itsCount] + " " + 00254 convertToString(itsRange[itsCount].min()) + ":" + 00255 convertToString(itsRange[itsCount].max()); 00256 writeText(outb, Point2D<int>(0,0), temp.c_str()); 00257 } 00258 else 00259 writeText(outb, Point2D<int>(0,0), itsNames[itsCount].c_str()); 00260 00261 //clean up by adding some boarder and colorizing 00262 Rectangle r(Point2D<int>(0,0), Dims(outb.getWidth(),outb.getHeight())); 00263 drawRectSquareCorners(outb ,r , (byte)255, 2); 00264 00265 Image<PixRGB<byte> > outbrgb = colorize(outb, itsCol[itsCount]); 00266 layout = vcat(outbrgb, layout); 00267 } 00268 00269 if (itsCount == itsTotal-1) 00270 itsCount = -1; 00271 00272 return layout; 00273 } 00274 00275 // ###################################################################### 00276 inline 00277 void StructurePlot::reset() 00278 { 00279 std::vector<LayerDecoder>::iterator iter(itsDecoder.begin()); 00280 while (iter != itsDecoder.end()) 00281 (iter++)->reset(); 00282 00283 itsN.clear(); 00284 } 00285 00286 // ###################################################################### 00287 inline 00288 uint StructurePlot::countSubs(const SimStructure& structure, uint depth) 00289 { 00290 if (depth > 0) 00291 for (uint i = 0; i < structure.numSubs(); ++i) 00292 { 00293 const SimStructure& temp(structure.getSub(i)); 00294 const uint mydepth = depth - 1; 00295 countSubs(temp, mydepth); //recursion = depth first count 00296 } 00297 00298 itsNames.push_back(structure.getName()); 00299 00300 //setup color 00301 if (structure.getName().find("Inh") == 0) 00302 { 00303 itsCol.push_back(ColorMap::GRADIENT(PixRGB<byte>(255,255,255), 00304 PixRGB<byte>(0,0,255))); 00305 LINFO("Assigning colormap for %s: blue", structure.getName().c_str()); 00306 } 00307 00308 else if (structure.getName().find("Exc") == 0) 00309 { 00310 itsCol.push_back(ColorMap::GRADIENT(PixRGB<byte>(255,255,255), 00311 PixRGB<byte>(255,0,0))); 00312 LINFO("Assigning colormap for %s: red", structure.getName().c_str()); 00313 } 00314 else 00315 { 00316 itsCol.push_back(ColorMap::JET()); 00317 LINFO("Assigning colormap for %s: jet", structure.getName().c_str()); 00318 } 00319 00320 return itsNames.size(); 00321 } 00322 00323 #endif 00324 00325 // ###################################################################### 00326 /* So things look consistent in everyone's emacs... */ 00327 /* Local Variables: */ 00328 /* indent-tabs-mode: nil */ 00329 /* End: */