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