00001 /*!@file SceneUnderstanding/TwoHalfDSketch.H */ 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: Lior Elazary <elazary@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/plugins/SceneUnderstanding/TwoHalfDSketch.H $ 00035 // $Id: TwoHalfDSketch.H 14179 2010-10-28 19:49:24Z lior $ 00036 // 00037 00038 #ifndef TwoHalfDSketch_H_DEFINED 00039 #define TwoHalfDSketch_H_DEFINED 00040 00041 #include "Image/OpenCVUtil.H" //Need to be first to avoid type def conf 00042 #include "Util/Types.H" 00043 #include "Image/Image.H" 00044 #include "Image/ImageSet.H" 00045 #include "Image/Pixels.H" 00046 #include "Image/Layout.H" 00047 #include "FeatureMatching/OriChamferMatching.H" 00048 #include "plugins/SceneUnderstanding/V2.H" 00049 #include "plugins/SceneUnderstanding/Contours.H" 00050 #include "plugins/SceneUnderstanding/Regions.H" 00051 #include "plugins/SceneUnderstanding/CornersFeatures.H" 00052 #include "plugins/SceneUnderstanding/SMap.H" 00053 #include "Simulation/SimEvents.H" 00054 #include "Simulation/SimModule.H" 00055 #include "GUI/ViewPort3D.H" 00056 00057 #include <vector> 00058 #include <string> 00059 00060 class SimEventTwoHalfDSketchPrior; 00061 00062 #define INVALID_PROB -1e10 00063 00064 class TwoHalfDSketch : public SimModule 00065 { 00066 public: 00067 00068 struct SurfaceState 00069 { 00070 Point2D<float> pos; 00071 Point2D<float> pos2; 00072 float a; 00073 float b; 00074 float e; 00075 float k1; //shearing in the x direction 00076 float k2; //shearing in the y direction 00077 float rot; //rotation 00078 float start; 00079 float end; 00080 double prob; 00081 int gibs; 00082 double scale; 00083 Point2D<float> aspect; 00084 Point2D<float> shear; 00085 float matchingScale; 00086 Polygon polygon; 00087 00088 00089 SurfaceState () : 00090 prob(INVALID_PROB) 00091 {} 00092 00093 00094 //Get a line up to scale and in the right position 00095 Line getLine(uint idx) 00096 { 00097 ASSERT(idx < polygon.getNumLines()); 00098 00099 Line l = polygon.getLine(idx); 00100 l.trans(pos); 00101 l.scale(1.0/matchingScale); 00102 return l; 00103 } 00104 00105 //Get the position up to scale 00106 Point2D<double> getPos() 00107 { 00108 return pos*(1.0/matchingScale); 00109 } 00110 00111 00112 Rectangle getBB() 00113 { 00114 Rectangle bb; 00115 00116 if(polygon.getNumLines() > 1) 00117 { 00118 00119 Line l = getLine(0); 00120 Point2D<int> p1 = (Point2D<int>)l.getP1(); 00121 int minX=p1.i; 00122 int minY=p1.j; 00123 int maxX=minX; 00124 int maxY=minY; 00125 for(uint i=0;i<polygon.getNumLines();i++) 00126 { 00127 Line l = getLine(i); 00128 Point2D<int> p1 = (Point2D<int>)l.getP1(); 00129 if(p1.i < minX) minX = p1.i; 00130 if(p1.j < minY) minY = p1.j; 00131 if(p1.i > maxX) maxX = p1.i; 00132 if(p1.j > maxY) maxY = p1.j; 00133 00134 Point2D<int> p2 = (Point2D<int>)l.getP2(); 00135 if(p2.i < minX) minX = p2.i; 00136 if(p2.j < minY) minY = p2.j; 00137 if(p2.i > maxX) maxX = p2.i; 00138 if(p2.j > maxY) maxY = p2.j; 00139 } 00140 // Using inclusive coordinates since it works well when the polygon has 00141 bb = Rectangle::tlbrI(minY,minX,maxY,maxX); 00142 } 00143 return bb; 00144 } 00145 }; 00146 00147 00148 void findMax(const Image<SurfaceState>& src, Point2D<int>& p, SurfaceState& maxval) 00149 { 00150 ASSERT(src.initialized()); 00151 Image<SurfaceState>::const_iterator aptr = src.begin(); 00152 const int w = src.getWidth(), h = src.getHeight(); 00153 p.i = 0; p.j = 0; maxval = *aptr; 00154 for (int j = 0; j < h; j ++) 00155 for (int i = 0; i < w; i ++) 00156 { 00157 if (aptr->prob > maxval.prob) { maxval = *aptr; p.i = i; p.j = j; } 00158 aptr++; 00159 } 00160 } 00161 00162 void drawDisk(Image<SurfaceState>& dst, const Point2D<int>& center, 00163 const int radius) 00164 { 00165 if (radius == 1) 00166 { 00167 if (dst.coordsOk(center)) dst.setVal(center.i + dst.getWidth() * center.j, SurfaceState()); 00168 return; 00169 } 00170 00171 for (int y = -radius; y <= radius; ++y) 00172 { 00173 int bound = int(sqrtf(float(squareOf(radius) - squareOf(y)))); 00174 for (int x = -bound; x <= bound; ++x) 00175 if (dst.coordsOk(x + center.i, y + center.j)) 00176 dst.setVal(x + center.i, y + center.j, SurfaceState()); 00177 } 00178 } 00179 00180 Image<float> getProbImage(const Image<SurfaceState>& src) 00181 { 00182 Image<float> probImg(src.getDims(), NO_INIT); 00183 ASSERT(src.initialized()); 00184 00185 for(uint i=0; i<src.size(); i++) 00186 probImg[i] = src[i].prob; 00187 00188 return probImg; 00189 } 00190 00191 00192 00193 TwoHalfDSketch(OptionManager& mgr, const std::string& descrName = "TwoHalfDSketch", 00194 const std::string& tagName = "TwoHalfDSketch"); 00195 00196 //! Destructor 00197 ~TwoHalfDSketch(); 00198 00199 void evolve(SimEventQueue& q); 00200 00201 Layout<PixRGB<byte> > getDebugImage(SimEventQueue& q); 00202 00203 00204 double calcNFA(Line& line); 00205 00206 void drawSurface(const SurfaceState& surface); 00207 00208 00209 Image<SurfaceState> proposeSurfaces(bool biasMode); 00210 void calcSurfaceLikelihood(SurfaceState& surface); 00211 double calcSurfaceEdgeLikelihood(SurfaceState& surface, Image<float>& edges, Image<float>& surfaceLum); 00212 double getEdgeProb(Point2D<int> loc, float ori); 00213 00214 double calcSurfaceLumLikelihood(SurfaceState& surface, Image<float>& edges, Image<float>& surfaceLum); 00215 double getSurfaceLumProb(Image<float>& data, Image<float>& model); 00216 Image<PixRGB<byte> > getSurfaceImage(const SurfaceState& surface); 00217 00218 double getLineProb(Point2D<int> p1, Point2D<int> p2, float ori, int& pixCount); 00219 00220 double getCost(OriChamferMatching& lm, Polygon& poly,Point2D<float> loc, bool biasMode = false); 00221 00222 Image<float> getSurfaceProbImage(Image<SurfaceState>& surfaceState); 00223 00224 00225 void printResults(float bias); 00226 00227 void optimizePolygon(SurfaceState& surfaceState); 00228 00229 double nfa(int n, int k, double p, double logNT); 00230 int isaligned(Point2D<int> loc, Image<float>& angles, float theta, float prec); 00231 double log_gamma_windschitl(double x); 00232 double log_gamma_lanczos(double x); 00233 00234 typedef struct 00235 { 00236 float vx[4]; 00237 float vy[4]; 00238 float ys,ye; 00239 int x,y; 00240 } rect_iter; 00241 00242 struct rect /* line segment with width */ 00243 { 00244 float x1,y1,x2,y2; /* first and second point of the line segment */ 00245 float width; /* rectangle width */ 00246 float x,y; /* center of the rectangle */ 00247 float theta; /* angle */ 00248 float dx,dy; /* vector with the line segment angle */ 00249 float prec; /* tolerance angle */ 00250 double p; /* probability of a point with angle within prec */ 00251 float sum; /* the sum of mag */ 00252 }; 00253 00254 00255 float inter_low(float x, float x1, float y1, float x2, float y2); 00256 float inter_hi(float x, float x1, float y1, float x2, float y2); 00257 void ri_del(rect_iter * iter); 00258 int ri_end(rect_iter * i); 00259 void ri_inc(rect_iter * i); 00260 rect_iter * ri_ini(struct rect * r); 00261 00262 00263 00264 protected: 00265 //! Callback for when a new ganglion output is ready 00266 SIMCALLBACK_DECLARE(TwoHalfDSketch, SimEventV2Output); 00267 00268 SIMCALLBACK_DECLARE(TwoHalfDSketch, SimEventContoursOutput); 00269 00270 //! Callback for every time we should save our outputs 00271 SIMCALLBACK_DECLARE(TwoHalfDSketch, SimEventSaveOutput); 00272 00273 ////! Callback for every time we have a user event 00274 SIMCALLBACK_DECLARE(TwoHalfDSketch, SimEventUserInput); 00275 00276 //! Should we show our debug info 00277 OModelParam<bool> itsShowDebug; 00278 00279 00280 private: 00281 Image<PixRGB<byte> > itsCurrentFrame; 00282 Image<float> itsLinesMag; 00283 Image<float> itsLinesOri; 00284 Image<float> itsEdgesDT; 00285 ImageSet<float> itsOriEdgesDT; 00286 Image<byte> itsSMap; 00287 std::vector<V2::LineSegment> itsLines; 00288 std::vector<Contours::Contour> itsContours; 00289 std::vector<CornersFeatures::CornerState> itsCorners; 00290 std::vector<SurfaceState> itsSurfaces; 00291 std::vector<SurfaceState> itsProposals; 00292 SurfaceState itsUserProposal; 00293 Polygon itsModel; 00294 OriChamferMatching itsOriChamferMatcher; 00295 double itsProposalThreshold; 00296 double itsAcceptedThreshold; 00297 Image<float> itsProposalsProb; 00298 Image<float> itsProposalsIdxs; 00299 float itsCurrentProb; 00300 uint itsCurrentIdx; 00301 bool itsBiasMode; 00302 float itsBias; 00303 int itsBiasId; 00304 00305 }; 00306 00307 /* ############################### V2 sim events ######################## */ 00308 class SimEventTwoHalfDSketchOutput : public SimEvent 00309 { 00310 public: 00311 SimEventTwoHalfDSketchOutput(SimModule* src, 00312 std::vector<TwoHalfDSketch::SurfaceState>& surfaces) : 00313 SimEvent(src), itsSurfaces(surfaces) 00314 {} 00315 00316 virtual ~SimEventTwoHalfDSketchOutput(){} 00317 std::vector<TwoHalfDSketch::SurfaceState> getSurfaces() { return itsSurfaces; } 00318 00319 private: 00320 const std::vector<TwoHalfDSketch::SurfaceState>& itsSurfaces; 00321 }; 00322 00323 00324 00325 // ###################################################################### 00326 /* So things look consistent in everyone's emacs... */ 00327 /* Local Variables: */ 00328 /* indent-tabs-mode: nil */ 00329 /* End: */ 00330 00331 #endif //