00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "Demo/SaliencyMT.H"
00039 #include "Demo/DemoOpts.H"
00040
00041
00042
00043
00044
00045 #define sml 2
00046 #define delta_min 3
00047 #define delta_max 4
00048 #define level_min 0
00049 #define level_max 2
00050 #define maxdepth (level_max + delta_max + 1)
00051 #define normtyp (VCXNORM_MAXNORM)
00052
00053
00054 #define IWEIGHT 0.7
00055 #define CWEIGHT 1.0
00056 #define OWEIGHT 1.0
00057 #define FWEIGHT 1.0
00058 #define SWEIGHT 0.7
00059
00060
00061 #define IMAGEWIDTH 160
00062 #define IMAGEHEIGHT 120
00063
00064
00065 #define RETINA 1
00066 #define WINNER 2
00067 #define LUMINANCE 3
00068 #define REDGREEN 4
00069 #define BLUEYELLOW 5
00070 #define ORI0 6
00071 #define ORI45 7
00072 #define ORI90 8
00073 #define ORI135 9
00074 #define CMAP 10
00075 #define FLICKER 11
00076 #define INTENSITY 12
00077 #define SKINHUE 13
00078
00079 #define numthreads 1
00080
00081
00082 void *SaliencyMT_CMAP(void *c)
00083 {
00084 SaliencyMT *d = (SaliencyMT *)c;
00085 d->computeCMAP();
00086 return NULL;
00087 }
00088
00089
00090 SaliencyMT::SaliencyMT(OptionManager& mgr,
00091 const std::string& descrName,
00092 const std::string& tagName):
00093 ModelComponent(mgr, descrName, tagName),
00094 itsNumThreads(&OPT_SMTnumThreads, this)
00095
00096 {
00097
00098 numWorkers = 0U;
00099
00100 }
00101
00102
00103 void SaliencyMT::start1()
00104 {
00105
00106
00107 pthread_mutex_init(&jobLock, NULL);
00108 pthread_mutex_init(&mapLock, NULL);
00109 pthread_cond_init(&jobCond, NULL);
00110
00111 LINFO("Starting with %u threads...", itsNumThreads.getVal());
00112
00113
00114 worker = new pthread_t[itsNumThreads.getVal()];
00115 for (uint i = 0; i < itsNumThreads.getVal(); i ++)
00116 {
00117 pthread_create(&worker[i], NULL, SaliencyMT_CMAP, (void *)this);
00118
00119
00120
00121 usleep(100000);
00122 }
00123 }
00124
00125
00126 void SaliencyMT::stop2()
00127 {
00128
00129 pthread_cond_destroy(&jobCond);
00130
00131
00132
00133
00134 delete [] worker;
00135 }
00136
00137
00138 SaliencyMT::~SaliencyMT()
00139 { }
00140
00141
00142 void SaliencyMT::newInput(Image< PixRGB<byte> > img, bool procFlicker)
00143 {
00144
00145
00146 pthread_mutex_lock(&mapLock);
00147 colima = img;
00148
00149
00150 outmap.freeMem();
00151 gotLum = false; gotRGBY = false; gotSkin = false;
00152 pthread_mutex_unlock(&mapLock);
00153
00154
00155 pthread_mutex_lock(&jobLock);
00156 jobQueue.clear();
00157
00158 jobQueue.push_back(jobData(INTENSITY, Gaussian5, IWEIGHT, 0.0F));
00159
00160 jobQueue.push_back(jobData(REDGREEN, Gaussian5, CWEIGHT, 0.0F));
00161
00162
00163
00164 jobQueue.push_back(jobData(ORI0, Oriented5, OWEIGHT, 0.0F));
00165 jobQueue.push_back(jobData(ORI45, Oriented5, OWEIGHT, 45.0F));
00166 jobQueue.push_back(jobData(ORI90, Oriented5, OWEIGHT, 90.0F));
00167 jobQueue.push_back(jobData(ORI135, Oriented5, OWEIGHT, 135.0F));
00168
00169 if (procFlicker)
00170 jobQueue.push_back(jobData(FLICKER, Gaussian5, FWEIGHT, 0.0F));
00171
00172 jobQueue.push_back(jobData(BLUEYELLOW, Gaussian5, CWEIGHT, 0.0F));
00173
00174 jobsTodo = jobQueue.size();
00175 pthread_mutex_unlock(&jobLock);
00176
00177
00178 pthread_cond_broadcast(&jobCond);
00179
00180 }
00181
00182
00183 bool SaliencyMT::outputReady()
00184 {
00185 bool ret = false;
00186
00187 pthread_mutex_lock(&jobLock);
00188 if (jobsTodo == 0U) ret = true;
00189 pthread_mutex_unlock(&jobLock);
00190
00191 return ret;
00192 }
00193
00194
00195 Image<float> SaliencyMT::getOutput()
00196 {
00197 Image<float> ret;
00198
00199 pthread_mutex_lock(&mapLock);
00200 ret = outmap;
00201 pthread_mutex_unlock(&mapLock);
00202
00203 return ret;
00204 }
00205
00206
00207
00208 void SaliencyMT::computeCMAP()
00209 {
00210 pthread_mutex_lock(&mapLock);
00211 uint myNum = numWorkers ++;
00212 pthread_mutex_unlock(&mapLock);
00213 LINFO(" ... worker %u ready.", myNum);
00214
00215 while(true)
00216 {
00217
00218 pthread_mutex_lock(&jobLock);
00219 jobData current(0, Gaussian5, 0.0F, 0.0F); bool nojobs = true;
00220 if (jobQueue.empty() == false)
00221 {
00222 current = jobQueue.front();
00223 jobQueue.pop_front();
00224 nojobs = false;
00225 }
00226 else
00227 pthread_cond_wait(&jobCond, &jobLock);
00228 pthread_mutex_unlock(&jobLock);
00229
00230
00231 if (nojobs) continue;
00232
00233
00234
00235
00236
00237 Image<float> curImage;
00238
00239
00240
00241 pthread_mutex_lock(&mapLock);
00242 switch(current.jobType)
00243 {
00244
00245
00246
00247
00248 case REDGREEN:
00249 if (gotRGBY == false)
00250 { getRGBY(colima, r, g, b, y, byte(25)); gotRGBY = true; }
00251 curImage = r - g;
00252 break;
00253
00254
00255 case BLUEYELLOW:
00256 if (gotRGBY == false)
00257 { getRGBY(colima, r, g, b, y, byte(25)); gotRGBY = true; }
00258 curImage = b - y;
00259 break;
00260
00261
00262 case SKINHUE:
00263 if (gotSkin == false)
00264 {
00265 skinima = hueDistance(colima, COL_SKIN_MUR, COL_SKIN_MUG,
00266 COL_SKIN_SIGR, COL_SKIN_SIGG,
00267 COL_SKIN_RHO);
00268 gotSkin = true;
00269 }
00270 curImage = skinima;
00271 break;
00272
00273
00274 case ORI0:
00275 case ORI45:
00276 case ORI90:
00277 case ORI135:
00278 case INTENSITY:
00279 if (gotLum == false)
00280 { lum = Image<float>(luminance(colima)); gotLum = true; }
00281 curImage = lum;
00282 break;
00283
00284
00285 case FLICKER:
00286 if (gotLum == false)
00287 { lum = Image<float>(luminance(colima)); gotLum = true; }
00288
00289 if (prev.initialized() == false)
00290 {
00291 prev = lum;
00292 curImage.resize(lum.getDims(), true);
00293 }
00294 else
00295 {
00296 curImage = lum - prev;
00297 prev = lum;
00298 }
00299 break;
00300
00301
00302 default:
00303 LERROR("What is going on around here?");
00304 curImage = lum;
00305 }
00306 pthread_mutex_unlock(&mapLock);
00307
00308
00309 ImageSet<float> pyr =
00310 buildPyrGeneric(curImage, 0, maxdepth,
00311 current.ptyp, current.orientation);
00312
00313
00314 Image<float> cmap(pyr[sml].getDims(), ZEROS);
00315
00316
00317 for (int delta = delta_min; delta <= delta_max; delta ++)
00318 for (int lev = level_min; lev <= level_max; lev ++)
00319 {
00320 Image<float> tmp = centerSurround(pyr, lev, lev + delta, true);
00321 tmp = downSize(tmp, cmap.getWidth(), cmap.getHeight());
00322 tmp = maxNormalize(tmp, MAXNORMMIN, MAXNORMMAX, normtyp);
00323 cmap += tmp;
00324 }
00325
00326 inplaceAddBGnoise(cmap, 25.0F);
00327
00328 if (normtyp == VCXNORM_MAXNORM)
00329 cmap = maxNormalize(cmap, MAXNORMMIN, MAXNORMMAX, normtyp);
00330 else
00331 cmap = maxNormalize(cmap, 0.0f, 0.0f, normtyp);
00332
00333
00334 if (current.weight != 1.0F) cmap *= current.weight;
00335
00336
00337 pthread_mutex_lock(&mapLock);
00338 if (outmap.initialized()) outmap += cmap;
00339 else outmap = cmap;
00340 pthread_mutex_unlock(&mapLock);
00341
00342 pthread_mutex_lock(&jobLock);
00343 -- jobsTodo;
00344
00345 pthread_mutex_unlock(&jobLock);
00346 }
00347 }
00348
00349
00350
00351
00352
00353