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 "CMapDemo/SaliencyCMapMT.H"
00039 #include "Demo/DemoOpts.H"
00040 #include "Corba/CorbaUtil.H"
00041 #include "Image/PyrBuilder.H"
00042 #include "Image/OpenCVUtil.H"
00043
00044 #include <sys/time.h>
00045 #include <errno.h>
00046
00047 #ifdef HAVE_OPENCV_CV_H
00048 #include <opencv/cv.h>
00049 #endif
00050
00051
00052
00053 #ifdef LocalCMapServer
00054
00055 #endif
00056
00057
00058
00059
00060
00061
00062 #define IWEIGHT 1.0
00063 #define CWEIGHT 1.0
00064 #define OWEIGHT 1.0
00065 #define FWEIGHT 4.0
00066 #define SWEIGHT 0.7
00067
00068
00069 #define IMAGEWIDTH 160
00070 #define IMAGEHEIGHT 120
00071
00072
00073 #define numthreads 1
00074
00075
00076 void *SaliencyMT_CMAP(void *c)
00077 {
00078 SaliencyMT *d = (SaliencyMT *)c;
00079 d->computeCMAP();
00080 return NULL;
00081 }
00082
00083
00084 SaliencyMT::SaliencyMT(OptionManager& mgr,CORBA::ORB_ptr orb, short saliencyMapLevel,
00085 const std::string& descrName,
00086 const std::string& tagName):
00087 ModelComponent(mgr, descrName, tagName), nCmapObj(0),
00088 itsNumThreads(&OPT_SMTnumThreads, this),
00089 SMBias(ImageSet<float>(14))
00090
00091 {
00092 numWorkers = 0U;
00093
00094 if (!getMultiObjectRef(orb, "saliency.CMapServers", CMap_ref, nCmapObj)){
00095 LFATAL("Can not find any object to bind with");
00096 }
00097 for(int i=0; i<nCmapObj; i++)
00098 CMap::_narrow(CMap_ref[i])->setSaliencyMapLevel(saliencyMapLevel);
00099 biasSM = false;
00100 }
00101
00102 void SaliencyMT::setBiasSM(bool val){
00103 biasSM = val;
00104 }
00105
00106
00107 void SaliencyMT::setSaliencyMapLevel(const short saliencyMapLevel){
00108
00109 for(int i=0; i<nCmapObj; i++)
00110 CMap::_narrow(CMap_ref[i])->setSaliencyMapLevel(saliencyMapLevel);
00111 }
00112
00113
00114
00115
00116 CMap_ptr SaliencyMT::getCmapRef(){
00117 static int current_obj = 0;
00118
00119
00120 current_obj = (current_obj+1)%nCmapObj;
00121
00122 LDEBUG("Using cmap object number %i\n", current_obj);
00123
00124 return CMap::_narrow(CMap_ref[current_obj]);
00125 }
00126
00127
00128 void SaliencyMT::start1()
00129 {
00130
00131
00132 pthread_mutex_init(&jobLock, NULL);
00133 pthread_mutex_init(&mapLock, NULL);
00134 pthread_mutex_init(&jobStatusLock, NULL);
00135 pthread_cond_init(&jobCond, NULL);
00136 pthread_cond_init(&jobDone, NULL);
00137
00138 LINFO("Starting with %u threads...", itsNumThreads.getVal());
00139
00140
00141 worker = new pthread_t[itsNumThreads.getVal()];
00142 for (uint i = 0; i < itsNumThreads.getVal(); i ++)
00143 {
00144 pthread_create(&worker[i], NULL, SaliencyMT_CMAP, (void *)this);
00145
00146
00147
00148 usleep(100000);
00149 }
00150 }
00151
00152
00153 void SaliencyMT::stop2()
00154 {
00155
00156 pthread_cond_destroy(&jobCond);
00157
00158
00159
00160
00161 delete [] worker;
00162 }
00163
00164
00165 SaliencyMT::~SaliencyMT(){ }
00166
00167
00168 void SaliencyMT::newInput(Image< PixRGB<byte> > img)
00169 {
00170
00171
00172 pthread_mutex_lock(&mapLock);
00173 colima = img;
00174
00175
00176 outmap.freeMem();
00177 gotLum = false; gotRGBY = false; gotSkin = false;
00178 pthread_mutex_unlock(&mapLock);
00179
00180
00181 pthread_mutex_lock(&jobLock);
00182 jobQueue.clear();
00183
00184 jobQueue.push_back(jobData(INTENSITY, Gaussian5, IWEIGHT, 0.0F));
00185
00186 jobQueue.push_back(jobData(REDGREEN, Gaussian5, CWEIGHT, 0.0F));
00187 jobQueue.push_back(jobData(BLUEYELLOW, Gaussian5, CWEIGHT, 0.0F));
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 jobsTodo = jobQueue.size();
00199 pthread_mutex_unlock(&jobLock);
00200
00201
00202 pthread_cond_broadcast(&jobCond);
00203
00204 }
00205
00206
00207 bool SaliencyMT::outputReady()
00208 {
00209 bool ret = false;
00210
00211 pthread_mutex_lock(&jobLock);
00212 if (jobsTodo == 0U) ret = true;
00213 pthread_mutex_unlock(&jobLock);
00214
00215 return ret;
00216 }
00217
00218
00219 Image<float> SaliencyMT::getOutput()
00220 {
00221 Image<float> ret;
00222
00223 pthread_mutex_lock(&mapLock);
00224 ret = outmap;
00225 pthread_mutex_unlock(&mapLock);
00226
00227 return ret;
00228 }
00229
00230
00231 Image<float> SaliencyMT::getSMap(Image< PixRGB<byte> > img)
00232 {
00233 Image<float> ret;
00234
00235 newInput(img);
00236
00237 LINFO("Getting smap");
00238
00239 pthread_mutex_lock(&jobStatusLock);
00240
00241 LINFO("Waiting for smap");
00242 struct timeval abstime_tv;
00243 gettimeofday(&abstime_tv, NULL);
00244
00245 struct timespec abstime;
00246 abstime.tv_sec = abstime_tv.tv_sec;
00247 abstime.tv_sec += 3;
00248 abstime.tv_nsec = 0;
00249
00250
00251 if (pthread_cond_timedwait(&jobDone, &jobStatusLock, &abstime) == ETIMEDOUT){
00252 LINFO("TIme out");
00253 }
00254 pthread_mutex_unlock(&jobStatusLock);
00255
00256 LINFO("Getting smap ");
00257
00258 pthread_mutex_lock(&mapLock);
00259 ret = outmap;
00260 pthread_mutex_unlock(&mapLock);
00261
00262 return ret;
00263 }
00264
00265
00266
00267 void SaliencyMT::setSMBias(ImageSet<float> &bias){
00268
00269 for(unsigned int i=0; i<bias.size(); i++){
00270 if (bias[i].initialized())
00271 SMBias[i] = bias[i];
00272 }
00273 }
00274
00275
00276
00277 void SaliencyMT::setBias(int type, std::vector<float> &bias)
00278 {
00279
00280 CMap::BiasSeq *curBias = NULL;
00281 switch (type) {
00282 case REDGREEN:
00283 curBias = &cmapBias.redgreen;
00284 break;
00285 case BLUEYELLOW:
00286 curBias = &cmapBias.blueyellow;
00287 break;
00288 case SKINHUE:
00289 curBias = &cmapBias.skinhue;
00290 break;
00291 case ORI0:
00292 curBias = &cmapBias.ori0;
00293 break;
00294 case ORI45:
00295 curBias = &cmapBias.ori45;
00296 break;
00297 case ORI90:
00298 curBias = &cmapBias.ori90;
00299 break;
00300 case ORI135:
00301 curBias = &cmapBias.ori135;
00302 break;
00303 case INTENSITY:
00304 curBias = &cmapBias.intensity;
00305 break;
00306 case FLICKER:
00307 curBias = &cmapBias.flicker;
00308 break;
00309 default:
00310 LINFO("Unknown type");
00311 }
00312
00313
00314
00315 if (curBias != NULL){
00316 curBias->length(bias.size());
00317 for(unsigned int i=0; i<bias.size(); i++)
00318 (*curBias)[i] = bias[i];
00319 }
00320
00321 }
00322
00323
00324
00325 void SaliencyMT::getBias(Image< PixRGB<byte> > &ima,
00326 std::vector<float> &bias, int type, Point2D<int> &loc)
00327 {
00328 PyramidType ptype = Gaussian5;
00329 float weight = 0;
00330 float ori = 0;
00331 Image<byte> curImage;
00332
00333 Image<float> local_lum;
00334 Image<byte> local_r, local_g, local_b, local_y;
00335 Image<float> local_skinima;
00336
00337 switch (type) {
00338 case REDGREEN:
00339 ptype = Gaussian5;
00340 ori = 0.0F;
00341 getRGBY(ima, local_r, local_g, local_b, local_y, byte(25));
00342 curImage = local_r - local_g;
00343 break;
00344
00345
00346 case BLUEYELLOW:
00347 ptype = Gaussian5;
00348 ori = 0.0F;
00349 getRGBY(ima, local_r, local_g, local_b, local_y, byte(25));
00350 curImage = local_b - local_y;
00351 break;
00352
00353
00354 case SKINHUE:
00355 ptype = Gaussian5;
00356 ori = 0.0F;
00357 local_skinima = hueDistance(ima, COL_SKIN_MUR, COL_SKIN_MUG,
00358 COL_SKIN_SIGR, COL_SKIN_SIGG,
00359 COL_SKIN_RHO);
00360 curImage = local_skinima;
00361 break;
00362
00363
00364 case ORI0:
00365 ptype = Oriented5;
00366 ori = 0.0F;
00367
00368 curImage = Image<byte>(luminance(ima));
00369 break;
00370 case ORI45:
00371 ptype = Oriented5;
00372 ori = 45.0F;
00373 curImage = Image<byte>(luminance(ima));
00374 break;
00375 case ORI90:
00376 ptype = Oriented5;
00377 ori = 90.0F;
00378 curImage = Image<byte>(luminance(ima));
00379 break;
00380 case ORI135:
00381 ptype = Oriented5;
00382 ori = 135.0F;
00383 curImage = Image<byte>(luminance(ima));
00384 break;
00385 case INTENSITY:
00386 ptype = Gaussian5;
00387 ori = 0.0F;
00388 curImage = Image<byte>(luminance(ima));
00389 break;
00390
00391
00392 case FLICKER:
00393 ptype = Gaussian5;
00394 ori = 0.0F;
00395 curImage = Image<byte>(luminance(ima));
00396 break;
00397
00398
00399 default:
00400 LERROR("What is going on around here?");
00401
00402 }
00403
00404 CMap_ptr CMap = getCmapRef();
00405 Point2DOrb locOrb;
00406 locOrb.i = loc.i; locOrb.j = loc.j;
00407
00408 ImageOrb *curImageOrb = image2Orb(curImage);
00409 CMap::BiasSeq *curBias = CMap->getBiasCMAP(*curImageOrb, ptype, ori, weight, locOrb);
00410 delete curImageOrb;
00411
00412
00413 if (curBias != NULL){
00414 curBias->length(bias.size());
00415 for(unsigned int i=0; i<bias.size(); i++)
00416 bias[i] = (*curBias)[i];
00417 }
00418 delete curBias;
00419
00420 }
00421
00422
00423
00424 void SaliencyMT::computeCMAP()
00425 {
00426 #ifndef HAVE_OPENCV
00427 LFATAL("OpenCV must be installed to use this function");
00428 #else
00429 pthread_mutex_lock(&mapLock);
00430 uint myNum = numWorkers ++;
00431 pthread_mutex_unlock(&mapLock);
00432 LINFO(" ... worker %u ready.", myNum);
00433
00434 while(true)
00435 {
00436
00437 pthread_mutex_lock(&jobLock);
00438 jobData current; bool nojobs = true;
00439 if (jobQueue.empty() == false)
00440 {
00441 current = jobQueue.front();
00442 jobQueue.pop_front();
00443 nojobs = false;
00444 }
00445 else
00446 pthread_cond_wait(&jobCond, &jobLock);
00447 pthread_mutex_unlock(&jobLock);
00448
00449
00450 if (nojobs) continue;
00451 LDEBUG("[%u] GOT: job %d", myNum, int(current.jobType));
00452
00453
00454
00455
00456 Image<byte> curImage;
00457
00458
00459
00460 pthread_mutex_lock(&mapLock);
00461
00462 switch(current.jobType)
00463 {
00464
00465
00466
00467
00468 case REDGREEN:
00469 if (gotRGBY == false)
00470 { getRGBY(colima, r, g, b, y, byte(25)); gotRGBY = true; }
00471 curImage = r - g;
00472 break;
00473
00474
00475 case BLUEYELLOW:
00476 if (gotRGBY == false)
00477 { getRGBY(colima, r, g, b, y, byte(25)); gotRGBY = true; }
00478 curImage = b - y;
00479 break;
00480
00481
00482 case SKINHUE:
00483 if (gotSkin == false)
00484 {
00485 skinima = hueDistance(colima, COL_SKIN_MUR, COL_SKIN_MUG,
00486 COL_SKIN_SIGR, COL_SKIN_SIGG,
00487 COL_SKIN_RHO);
00488 gotSkin = true;
00489 }
00490 curImage = skinima;
00491 break;
00492
00493
00494 case ORI0:
00495 if (gotLum == false)
00496 { lum = Image<byte>(luminance(colima)); gotLum = true; }
00497 curImage = lum;
00498 break;
00499 case ORI45:
00500 if (gotLum == false)
00501 { lum = Image<byte>(luminance(colima)); gotLum = true; }
00502 curImage = lum;
00503 break;
00504 case ORI90:
00505 if (gotLum == false)
00506 { lum = Image<byte>(luminance(colima)); gotLum = true; }
00507 curImage = lum;
00508 break;
00509 case ORI135:
00510 if (gotLum == false)
00511 { lum = Image<byte>(luminance(colima)); gotLum = true; }
00512 curImage = lum;
00513 break;
00514 case INTENSITY:
00515 if (gotLum == false)
00516 { lum = Image<byte>(luminance(colima)); gotLum = true; }
00517 curImage = lum;
00518 break;
00519
00520
00521 case FLICKER:
00522 if (gotLum == false)
00523 { lum = Image<byte>(luminance(colima)); gotLum = true; }
00524
00525 if (prev.initialized() == false)
00526 {
00527 prev = lum;
00528 curImage.resize(lum.getDims(), true);
00529 }
00530 else
00531 {
00532 curImage = lum - prev;
00533 prev = lum;
00534 }
00535 break;
00536
00537
00538 default:
00539 LERROR("What is going on around here?");
00540 curImage = lum;
00541 }
00542 pthread_mutex_unlock(&mapLock);
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564 Image<float> cmap = curImage;
00565
00566
00567 Image<float> biasedCMap(cmap.getWidth()-SMBias[current.jobType].getWidth()+1,
00568 cmap.getHeight()-SMBias[current.jobType].getHeight()+1,
00569 NO_INIT);
00570
00571 if (biasSM){
00572 if (SMBias[current.jobType].initialized())
00573 cvMatchTemplate(img2ipl(cmap),
00574 img2ipl(SMBias[current.jobType]),
00575 img2ipl(biasedCMap),
00576
00577 CV_TM_SQDIFF);
00578
00579
00580 }
00581
00582
00583
00584 pthread_mutex_lock(&mapLock);
00585 cmaps[current.jobType] = cmap;
00586
00587 if (biasSM){
00588 if (outmap.initialized()) outmap += biasedCMap;
00589 else outmap = biasedCMap;
00590 } else {
00591 if (outmap.initialized()) outmap += cmap;
00592 else outmap = cmap;
00593 }
00594
00595 pthread_mutex_unlock(&mapLock);
00596
00597 pthread_mutex_lock(&jobLock);
00598 -- jobsTodo;
00599 LDEBUG("done with job %d, %u todo...", int(current.jobType),jobsTodo);
00600
00601 if (jobsTodo == 0U)
00602 pthread_cond_signal(&jobDone);
00603
00604
00605 pthread_mutex_unlock(&jobLock);
00606 }
00607 #endif
00608 }
00609
00610
00611
00612
00613
00614