00001 #include "RegSaliency.H"
00002 #include "Image/PyrBuilder.H"
00003 #include "Util/Timer.H"
00004
00005
00006 #define IWEIGHT 0.7
00007 #define CWEIGHT 1.0
00008 #define OWEIGHT 1.0
00009 #define FWEIGHT 1.0
00010 #define SWEIGHT 0.7
00011 #define COLOR_THRESH 0.1F
00012
00013 #define delta_min 3
00014 #define delta_max 4
00015 #define level_min 0
00016 #define level_max 2
00017 #define maxdepth (level_max + delta_max + 1)
00018 #define sml 3
00019 #define normtyp VCXNORM_FANCY
00020 #define MAXNORMITERS 1
00021
00022
00023 RegSaliency::RegSaliency(OptionManager& mgr,
00024 const std::string& descrName,
00025 const std::string& tagName):
00026 ModelComponent(mgr, descrName, tagName)
00027 {
00028 gotLum = false; gotRGBY = false; gotSaliency = false;
00029 numMotionDirs = 4;
00030 numOrientationDirs = 4;
00031
00032
00033 }
00034
00035
00036 void RegSaliency::start1()
00037 {
00038 reichardtPyr = new ReichardtPyrBuilder<float>*[numMotionDirs];
00039 for(int i=0;i<numMotionDirs;i++)
00040 {
00041 double direction = 360.0*double(i)/double(numMotionDirs);
00042 reichardtPyr[i] =
00043 new ReichardtPyrBuilder<float>(cos(direction*M_PI/180.0),-sin(direction*M_PI/180.0),
00044 Gaussian5,direction+90.0);
00045 }
00046 }
00047
00048
00049 void RegSaliency::stop2()
00050 {
00051 for(int i=0;i<numMotionDirs;i++)
00052 {
00053 delete reichardtPyr[i];
00054 }
00055 delete [] reichardtPyr;
00056 }
00057
00058
00059 RegSaliency::~RegSaliency()
00060 { }
00061
00062
00063 void RegSaliency::doInput(const Image< PixRGB<byte> > img)
00064 {
00065
00066 Image<PixRGB<float> > fimg = img;
00067 colima = Image<PixRGB<float> >(fimg);
00068 if(outmap.initialized())
00069 outmap.clear();
00070
00071 gotLum = false; gotRGBY = false;
00072
00073
00074 Timer tim;
00075 printf("Timing saliency\n");
00076 tim.reset();
00077 runSaliency();
00078 LINFO("Done! %fms", tim.getSecs() * 1000.0F);
00079 }
00080
00081
00082 bool RegSaliency::outputReady()
00083 {
00084 return gotSaliency;
00085 }
00086
00087
00088 Image<float> RegSaliency::getOutput()
00089 {
00090 return convmap;
00091 }
00092
00093 Image<float> RegSaliency::getIMap()
00094 {
00095 return intensityMap;
00096 }
00097
00098 Image<float> RegSaliency::getCMap()
00099 {
00100 return colorMap;
00101 }
00102
00103 Image<float> RegSaliency::getOMap()
00104 {
00105 return orientationMap;
00106 }
00107
00108 Image<float> RegSaliency::getFMap()
00109 {
00110 return flickerMap;
00111 }
00112
00113 Image<float> RegSaliency::getMMap()
00114 {
00115 return motionMap;
00116 }
00117
00118 Image<float> RegSaliency::getInertiaMap()
00119 {
00120 return itsInertiaMap;
00121 }
00122
00123 Image<float> RegSaliency::getInhibitionMap()
00124 {
00125 return itsInhibitionMap;
00126 }
00127
00128
00129
00130 Image<float> RegSaliency::postChannel(Image<float> curImage, PyramidType ptyp, float orientation, float weight, Image<float>& outmap)
00131 {
00132
00133 ImageSet<float> pyr =
00134 buildPyrGeneric(curImage, 0, maxdepth, ptyp, orientation);
00135
00136 Image<float> cmap = processPyramid(pyr);
00137
00138
00139 if (weight != 1.0F) cmap *= weight;
00140
00141 if (outmap.initialized()) outmap += cmap;
00142 else outmap = cmap;
00143 return cmap;
00144 }
00145
00146
00147 Image<float> RegSaliency::processPyramid(ImageSet<float> pyr)
00148 {
00149
00150 Image<float> cmap;
00151
00152
00153 for (int delta = delta_min; delta <= delta_max; delta ++)
00154 for (int lev = level_min; lev <= level_max; lev ++)
00155 {
00156 Image<float> tmp = centerSurround(pyr, lev, lev + delta, true);
00157 tmp = downSize(tmp, pyr[sml].getWidth(), pyr[sml].getHeight());
00158 tmp = maxNormalize(tmp, MAXNORMMIN, MAXNORMMAX, normtyp,MAXNORMITERS);
00159 if(cmap.initialized())
00160 cmap += tmp;
00161 else
00162 cmap = tmp;
00163 }
00164
00165 inplaceAddBGnoise(cmap, 25.0F);
00166
00167
00168 if (normtyp == VCXNORM_MAXNORM)
00169 cmap = maxNormalize(cmap, MAXNORMMIN, MAXNORMMAX, normtyp,MAXNORMITERS);
00170 else
00171 cmap = maxNormalize(cmap, 0.0f, 0.0f, normtyp,MAXNORMITERS);
00172
00173
00174 return cmap;
00175 }
00176
00177
00178
00179 void RegSaliency::calcIntensity(const Image<PixRGB<float> > & colImage, Image<float>& outmap)
00180 {
00181 if(gotLum == false)
00182 {
00183 curLum = luminance(colImage);
00184
00185 curLumPyr = buildPyrGeneric(curLum, 0, maxdepth, Gaussian5, 0.0F);
00186 Image<float> cmap = processPyramid(curLumPyr);
00187
00188 if (IWEIGHT != 1.0F) cmap *= IWEIGHT;
00189
00190 if (outmap.initialized()) outmap += cmap;
00191 else outmap = cmap;
00192 intensityMap=cmap;
00193 gotLum = true;
00194 }
00195 }
00196
00197
00198 void RegSaliency::calcColor(const Image<PixRGB<float> > & colImage, Image<float>& outmap)
00199 {
00200
00201 if(gotRGBY == false)
00202 {
00203 getRGBY(colImage,rg,by,COLOR_THRESH);
00204 gotRGBY = true;
00205 }
00206 Image<float> col=(rg+by)/2.0F;
00207 colorMap = postChannel(col,Gaussian5,0.0F,CWEIGHT,outmap);
00208 }
00209
00210 void RegSaliency::calcOrientation(const Image<PixRGB<float> > & colImage, float orientation, Image<float>& outmap)
00211 {
00212 if(gotLum == false)
00213 {
00214 curLum = luminance(colImage);
00215 gotLum = true;
00216 }
00217 Image<float> o = postChannel(curLum,Oriented5,orientation,OWEIGHT,outmap);
00218 if(orientationMap.initialized())
00219 orientationMap += o;
00220 else
00221 orientationMap = o;
00222 }
00223
00224 void RegSaliency::calcFlicker(const Image<PixRGB<float> >& colImage, Image<float>& outmap)
00225 {
00226 Image<float> curImage;
00227 if(gotLum == false)
00228 {
00229 curLum = luminance(colima);
00230 gotLum = true;
00231 }
00232 if (prevLum.initialized() == false)
00233 {
00234 prevLum = curLum;
00235 curImage = Image<float>(curLum.getDims(), ZEROS);
00236 }
00237 else
00238 {
00239 curImage = curLum - prevLum;
00240 prevLum = curLum;
00241 }
00242 flickerMap = postChannel(curImage,Gaussian5,0.0F,FWEIGHT,outmap);
00243 }
00244
00245 void RegSaliency::calcMotion(const Image<PixRGB<float> > & colImage, int motionIndex)
00246 {
00247 if(gotLum == false)
00248 {
00249 curLum = luminance(colImage);
00250 gotLum = true;
00251 }
00252
00253 ImageSet<float> motPyr = (reichardtPyr[motionIndex])->build(curLum,0,maxdepth);
00254 Image<float> m = processPyramid(motPyr);
00255 if(motionMap.initialized())
00256 motionMap += m;
00257 else
00258 motionMap = m;
00259 }
00260
00261
00262 void RegSaliency::runSaliency()
00263 {
00264 Timer tim;
00265 gotSaliency = false;
00266 tim.reset();
00267 calcIntensity(colima,outmap);
00268
00269
00270 tim.reset();
00271 calcColor(colima,outmap);
00272
00273 tim.reset();
00274
00275
00276 for(int i=0;i<numOrientationDirs;i++)
00277 {
00278 calcOrientation(colima,180.0*double(i)/double(numOrientationDirs),outmap);
00279 }
00280
00281 tim.reset();
00282 calcFlicker(colima,outmap);
00283
00284
00285 for(int i=0;i<numMotionDirs;i++)
00286 {
00287 calcMotion(colima,i);
00288 }
00289
00290
00291 motionMap = maxNormalize(motionMap, MAXNORMMIN, MAXNORMMAX, normtyp,MAXNORMITERS);
00292
00293 if (outmap.initialized()) outmap += motionMap;
00294 else outmap = motionMap;
00295
00296 convmap = outmap;
00297 gotSaliency = true;
00298 }