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 <stdlib.h>
00039 #include <time.h>
00040 #include <iostream>
00041 #include <unistd.h>
00042 #include <fcntl.h>
00043 #include <sys/types.h>
00044 #include <sys/stat.h>
00045 #include <signal.h>
00046 #include "Image/ColorOps.H"
00047 #include "Image/MathOps.H"
00048 #include "Image/Image.H"
00049 #include "Image/ImageSet.H"
00050 #include "Image/Pixels.H"
00051 #include "Image/PyramidOps.H"
00052 #include "Image/ShapeOps.H"
00053 #include "Image/Transforms.H"
00054 #include "Image/fancynorm.H"
00055 #include "Util/Assert.H"
00056 #include "Util/Timer.H"
00057 #include "Util/Types.H"
00058 #include "Component/ModelManager.H"
00059 #include "Corba/Objects/CMapSK.hh"
00060 #include "Corba/ImageOrbUtil.H"
00061 #include "Corba/Objects/CMapServer.H"
00062 #include "Corba/CorbaUtil.H"
00063
00064
00065
00066
00067
00068
00069 #define delta_min 3
00070 #define delta_max 4
00071 #define level_min 0
00072 #define level_max 2
00073 #define maxdepth (level_max + delta_max + 1)
00074 #define normtyp (VCXNORM_MAXNORM)
00075
00076
00077
00078
00079 #define NBCMAP2 7
00080
00081 #define PRESCALE 2
00082
00083 CORBA::ORB_var orb;
00084 CosNaming::Name objectName;
00085
00086 bool Debug = false;
00087
00088 #ifndef LocalCMapServer
00089
00090 void terminate(int s)
00091 {
00092 LERROR("*** INTERRUPT ***");
00093 unbindObject(orb, "saliency", "CMapServers", objectName);
00094 orb->shutdown(0);
00095 }
00096 #endif
00097
00098 static omni_mutex BiasCenterSurroundMutex;
00099
00100 class BiasCenterSurroundThread : public omni_thread {
00101
00102 public:
00103 BiasCenterSurroundThread(Image<float> &cmap, ImageSet<float> &pyr,
00104 int lev1, int lev2, float bias):
00105 th_cmap(cmap), th_pyr(pyr), th_lev1(lev1), th_lev2(lev2), th_bias(bias){
00106
00107 start_undetached();
00108 }
00109
00110 private:
00111 Image<float> &th_cmap;
00112 ImageSet<float> &th_pyr;
00113 int th_lev1, th_lev2;
00114 float th_bias;
00115
00116 void* run_undetached(void *ptr){
00117
00118 Image<float> tmp = centerSurround(th_pyr, th_lev1, th_lev2, true);
00119 inplaceNormalize(tmp, 0.0F, 255.0F);
00120
00121
00122 for (Image<float>::iterator itr = tmp.beginw(), stop = tmp.endw();
00123 itr != stop; ++itr) {
00124 *itr = 255.0F - fabs((*itr) - th_bias);
00125 }
00126
00127 tmp = downSize(tmp, th_cmap.getWidth(), th_cmap.getHeight());
00128
00129
00130 tmp = maxNormalize(tmp, MAXNORMMIN, MAXNORMMAX, normtyp);
00131 BiasCenterSurroundMutex.lock();
00132 th_cmap += tmp;
00133 BiasCenterSurroundMutex.unlock();
00134
00135 return NULL;
00136 }
00137 };
00138
00139 class CenterSurroundThread : public omni_thread {
00140
00141 public:
00142 CenterSurroundThread(Image<float> &cmap, ImageSet<float> &pyr, int lev1, int lev2):
00143 th_cmap(cmap), th_pyr(pyr), th_lev1(lev1), th_lev2(lev2){
00144
00145 start_undetached();
00146 }
00147
00148 private:
00149 Image<float> &th_cmap;
00150 ImageSet<float> &th_pyr;
00151 int th_lev1, th_lev2;
00152
00153 void* run_undetached(void *ptr){
00154
00155 Image<float> tmp = centerSurround(th_pyr, th_lev1, th_lev2, true);
00156 inplaceNormalize(tmp, 0.0F, 255.0F);
00157
00158 if (tmp.getWidth() >= th_cmap.getWidth())
00159 tmp = downSize(tmp, th_cmap.getWidth(), th_cmap.getHeight());
00160 else
00161 tmp = quickInterpolate(tmp, th_cmap.getWidth()/tmp.getWidth());
00162
00163 tmp = maxNormalize(tmp, MAXNORMMIN, MAXNORMMAX, normtyp);
00164
00165 BiasCenterSurroundMutex.lock();
00166 th_cmap += tmp;
00167 BiasCenterSurroundMutex.unlock();
00168
00169 return NULL;
00170 }
00171 };
00172
00173 void CMap_i::shutdown() {
00174
00175 unbindObject(orb,"saliency", "CMapServers", objectName);
00176 orb->shutdown(0);
00177 }
00178
00179 void CMap_i::setSaliencyMapLevel(const short sml){
00180 saliencyMapLevel = sml;
00181 }
00182
00183
00184
00185
00186 CMap::BiasSeq* CMap_i::getBiasCMAP(const ImageOrb& img, const short ptyp,
00187 const float ori, const float coeff,
00188 const Point2DOrb& loc)
00189 {
00190
00191 Image<byte> image;
00192 orb2Image(img, image);
00193
00194
00195 Image<float> fimg = image;
00196
00197 ImageSet<float> pyr = buildPyrGeneric(fimg, 0, maxdepth,
00198 (PyramidType)ptyp, ori);
00199
00200
00201
00202
00203 CMap::BiasSeq *bias = new CMap::BiasSeq;
00204 bias->length(6);
00205
00206
00207 int ii=0;
00208 for (int delta = delta_min; delta <= delta_max; delta ++)
00209 for (int lev = level_min; lev <= level_max; lev ++)
00210 {
00211 Image<float> tmp = centerSurround(pyr, lev, lev + delta, true);
00212 inplaceNormalize(tmp, 0.0F, 255.0F);
00213
00214 if (loc.i >= 0 && loc.j >=0){
00215
00216
00217 Point2D<int> newp((int)((float)loc.i * ((float)tmp.getWidth() / (float)fimg.getWidth())),
00218 (int)((float)loc.j * ((float)tmp.getHeight() / (float)fimg.getHeight())) );
00219 (*bias)[ii] = (float)tmp.getVal(newp);
00220
00221
00222
00223
00224 }
00225
00226 ii++;
00227 }
00228
00229
00230 return bias;
00231 }
00232
00233 ImageOrb* CMap_i::computeCMAP(const ImageOrb& img, const short ptyp, const float ori, const float coeff){
00234
00235
00236
00237 static double avrtime = 0;
00238 static int avgn = 0;
00239 double time_taken;
00240 Timer time(1000000);
00241 if (Debug) {
00242 time.reset();
00243 }
00244
00245
00246 Image<byte> image;
00247 orb2Image(img, image);
00248 Image<float> fimg = image;
00249
00250
00251 ImageSet<float> pyr = buildPyrGeneric(fimg, 0, maxdepth,
00252 (PyramidType)ptyp, ori);
00253
00254
00255 Image<float> cmap(pyr[saliencyMapLevel].getDims(), ZEROS);
00256
00257 int ii=0;
00258
00259 CenterSurroundThread *workth[25];
00260
00261
00262 for (int delta = delta_min; delta <= delta_max; delta ++)
00263 for (int lev = level_min; lev <= level_max; lev ++)
00264 {
00265
00266 workth[ii] = new CenterSurroundThread(cmap,pyr, lev, lev + delta);
00267 ii++;
00268 }
00269
00270
00271 for (int i=0; i<ii; i++)
00272 workth[i]->join(NULL);
00273
00274
00275
00276 if (normtyp == VCXNORM_MAXNORM)
00277 cmap = maxNormalize(cmap, MAXNORMMIN, MAXNORMMAX, normtyp);
00278 else
00279 cmap = maxNormalize(cmap, 0.0f, 0.0f, normtyp);
00280
00281
00282 if (coeff != 1.0F) cmap *= coeff;
00283
00284 if (Debug) {
00285 time_taken = time.getSecs();
00286 avrtime += time_taken;
00287 ++avgn;
00288 LINFO("CMap stats: agvn=%i avgtime=%0.4f time_taken=%f ptype=%i ori=%f coeff=%f",
00289 avgn, avrtime/(double)avgn, time_taken, (int)ptyp, ori, coeff);
00290 }
00291
00292 return image2Orb(cmap);
00293
00294
00295 }
00296
00297
00298 ImageOrb* CMap_i::computeCMAP2(const ImageOrb& img1, const ImageOrb& img2,
00299 const short ptyp, const float ori, const float coeff){
00300
00301 static double avrtime = 0;
00302 static int avgn = 0;
00303 double time_taken;
00304 Timer time(1000000);
00305 if (Debug) {
00306
00307 time.reset();
00308 }
00309
00310 Image<byte> image1;
00311 orb2Image(img1, image1);
00312
00313 Image<byte> image2;
00314 orb2Image(img2, image2);
00315
00316
00317 Image<float> fimg = image1-image2;
00318
00319 Image<float> *cmap = computeCMAP(fimg, (PyramidType)ptyp, ori, coeff);
00320 Image<byte> cmap_byte = *cmap;
00321 delete cmap;
00322
00323 if (Debug) {
00324 time_taken = time.getSecs();
00325 avrtime += time_taken;
00326 ++avgn;
00327 LINFO("CMap2 stats: agvn=%i avgtime=%0.4f time_taken=%f ptype=%i ori=%f coeff=%f",
00328 avgn, avrtime/(double)avgn, time_taken, (int)ptyp, ori, coeff);
00329 }
00330 return image2Orb(cmap_byte);
00331 }
00332
00333 ImageOrb* CMap_i::computeFlickerCMAP(const ImageOrb& img, const short ptyp, const float ori, const float coeff){
00334
00335 static double avrtime = 0;
00336 static int avgn = 0;
00337 double time_taken;
00338 Timer time(1000000);
00339 if (Debug) {
00340 time.reset();
00341 }
00342 static Image<float> previmg;
00343
00344
00345 Image<byte> image;
00346 orb2Image(img, image);
00347
00348
00349 Image<float> fimg = image;
00350 if (previmg.initialized() == false) previmg = fimg;
00351
00352 previmg -= fimg;
00353 Image<float> *cmap = computeCMAP(previmg, (PyramidType)ptyp, ori, coeff);
00354 previmg = fimg;
00355 Image<byte> cmap_byte = *cmap;
00356
00357 delete cmap;
00358
00359 if (Debug) {
00360 time_taken = time.getSecs();
00361 avrtime += time_taken;
00362 ++avgn;
00363 LINFO("FilckerCmap stats: agvn=%i avgtime=%0.4f time_taken=%f ptype=%i ori=%f coeff=%f",
00364 avgn, avrtime/(double)avgn, time_taken, (int)ptyp, ori, coeff);
00365 }
00366
00367 return image2Orb(cmap_byte);
00368 }
00369
00370 ImageOrb* CMap_i::computeBiasCMAP(const ImageOrb& img, const short ptyp,
00371 const float ori, const float coeff,
00372 const CMap::BiasSeq& bias){
00373
00374 static double avrtime = 0;
00375 static int avgn = 0;
00376 double time_taken;
00377 Timer time(1000000);
00378 if (Debug) {
00379 time.reset();
00380 }
00381
00382
00383 Image<byte> image;
00384 orb2Image(img, image);
00385 Image<float> fimg = image;
00386
00387
00388 ImageSet<float> pyr = buildPyrGeneric(fimg, 0, maxdepth,
00389 (PyramidType)ptyp, ori);
00390
00391
00392 Image<float> cmap(pyr[saliencyMapLevel].getDims(), ZEROS);
00393
00394 if (Debug) {
00395 LINFO("Bias map with: ");
00396 for (uint i=0; i<bias.length(); i++)
00397 printf("%f ", bias[i]);
00398 printf("\n");
00399 }
00400
00401
00402
00403 int ii=0;
00404
00405 BiasCenterSurroundThread *workth[25];
00406
00407 for (int delta = delta_min; delta <= delta_max; delta ++)
00408 for (int lev = level_min; lev <= level_max; lev ++)
00409 {
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427 workth[ii] = new BiasCenterSurroundThread(cmap,pyr, lev, lev + delta, bias[ii]);
00428 ii++;
00429
00430 }
00431
00432
00433 for (int i=0; i<ii; i++)
00434 workth[i]->join(NULL);
00435
00436 if (normtyp == VCXNORM_MAXNORM)
00437 cmap = maxNormalize(cmap, MAXNORMMIN, MAXNORMMAX, normtyp);
00438 else
00439 cmap = maxNormalize(cmap, 0.0f, 0.0f, normtyp);
00440
00441
00442 if (coeff != 1.0F) cmap *= coeff;
00443
00444 if (Debug) {
00445 time_taken = time.getSecs();
00446 avrtime += time_taken;
00447 ++avgn;
00448 LINFO("CMap stats: agvn=%i avgtime=%0.4f time_taken=%f ptype=%i ori=%f coeff=%f",
00449 avgn, avrtime/(double)avgn, time_taken, (int)ptyp, ori, coeff);
00450 }
00451
00452 return image2Orb(cmap);
00453 }
00454
00455
00456
00457 Image<float> *CMap_i::computeCMAP(const Image<float>& fimg, const PyramidType ptyp, const float ori, const float coeff)
00458 {
00459
00460
00461 ImageSet<float> pyr = buildPyrGeneric(fimg, 0, maxdepth,
00462 ptyp, ori);
00463
00464
00465 Image<float> *cmap = new Image<float>(pyr[saliencyMapLevel].getDims(), ZEROS);
00466
00467
00468
00469 for (int delta = delta_min; delta <= delta_max; delta ++)
00470 for (int lev = level_min; lev <= level_max; lev ++)
00471 {
00472 Image<float> tmp = centerSurround(pyr, lev, lev + delta, true);
00473 tmp = downSize(tmp, cmap->getWidth(), cmap->getHeight());
00474
00475 inplaceAddBGnoise(tmp, 255.0);
00476 tmp = maxNormalize(tmp, MAXNORMMIN, MAXNORMMAX, normtyp);
00477 *cmap += tmp;
00478 }
00479 if (normtyp == VCXNORM_MAXNORM)
00480 *cmap = maxNormalize(*cmap, MAXNORMMIN, MAXNORMMAX, normtyp);
00481 else
00482 *cmap = maxNormalize(*cmap, 0.0f, 0.0f, normtyp);
00483
00484
00485 if (coeff != 1.0F) *cmap *= coeff;
00486
00487
00488 return cmap;
00489 }
00490
00491
00492 Image<float> *CMap_i::computeBiasCMAP(const Image<float>& fimg, const PyramidType ptyp,
00493 const float ori, const float coeff,
00494 const CMap::BiasSeq& bias)
00495 {
00496
00497 ImageSet<float> pyr = buildPyrGeneric(fimg, 0, maxdepth,
00498 ptyp, ori);
00499
00500
00501 Image<float> *cmap = new Image<float>(pyr[saliencyMapLevel].getDims(), ZEROS);
00502
00503 if (Debug) {
00504 LINFO("Bias map with: ");
00505 for (uint i=0; i<bias.length(); i++)
00506 printf("%f ", bias[i]);
00507 printf("\n");
00508 }
00509
00510
00511
00512 int ii=0;
00513 for (int delta = delta_min; delta <= delta_max; delta ++)
00514 for (int lev = level_min; lev <= level_max; lev ++)
00515 {
00516 Image<float> tmp = centerSurround(pyr, lev, lev + delta, true);
00517 inplaceNormalize(tmp, 0.0F, 255.0F);
00518
00519
00520 for (Image<float>::iterator itr = tmp.beginw(), stop = tmp.endw();
00521 itr != stop; ++itr) {
00522 *itr = 255.0F - fabs((*itr) - bias[ii]);
00523 }
00524
00525 tmp = downSize(tmp, cmap->getWidth(), cmap->getHeight());
00526
00527
00528 tmp = maxNormalize(tmp, MAXNORMMIN, MAXNORMMAX, normtyp);
00529 *cmap += tmp;
00530 ii++;
00531 }
00532 if (normtyp == VCXNORM_MAXNORM)
00533 *cmap = maxNormalize(*cmap, MAXNORMMIN, MAXNORMMAX, normtyp);
00534 else
00535 *cmap = maxNormalize(*cmap, 0.0f, 0.0f, normtyp);
00536
00537
00538 *cmap *= coeff;
00539
00540 return cmap;
00541 }
00542
00543
00544 int main(int argc, char **argv){
00545
00546 MYLOGVERB = LOG_INFO;
00547
00548
00549 ModelManager manager("CMap Object");
00550
00551 if (manager.parseCommandLine((const int)argc, (const char**)argv, "", 0, 0) == false)
00552 return(1);
00553
00554
00555 if (manager.debugMode()){
00556 Debug = true;
00557 } else {
00558 LINFO("Running as a daemon. Set --debug to see any errors.");
00559
00560
00561 pid_t pid = fork();
00562 if (pid < 0)
00563 LFATAL("Can not fork");
00564
00565 if (pid > 0)
00566 exit(0);
00567
00568
00569 umask(0);
00570
00571
00572 pid_t sid = setsid();
00573 if (sid < 0)
00574 LFATAL("Can not become independent");
00575
00576 fclose(stdin);
00577 fclose(stdout);
00578 fclose(stderr);
00579
00580 }
00581
00582 signal(SIGHUP, terminate); signal(SIGINT, terminate);
00583 signal(SIGQUIT, terminate); signal(SIGTERM, terminate);
00584 signal(SIGALRM, terminate);
00585
00586
00587 orb = CORBA::ORB_init(argc, argv);
00588
00589 CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
00590 PortableServer::POA_var poa = PortableServer::POA::_narrow(obj);
00591
00592 CMap_i* cmap = new CMap_i();
00593
00594 PortableServer::ObjectId_var cmapid = poa->activate_object(cmap);
00595
00596
00597 obj = cmap->_this();
00598 CORBA::String_var sior(orb->object_to_string(obj));
00599 std::cerr << "'" << (char*)sior << "'" << "\n";
00600
00601 if( !bindObjectToName(orb, obj, "saliency", "CMapServers", "CMap", objectName) ){
00602 LFATAL("Can not bind to name service");
00603 return 1;
00604 }
00605 cmap->_remove_ref();
00606
00607 PortableServer::POAManager_var pman = poa->the_POAManager();
00608 pman->activate();
00609
00610 try {
00611 manager.start();
00612
00613 orb->run();
00614 } catch (...) {
00615 LINFO("Error starting server");
00616 }
00617
00618 LINFO("Shutting down");
00619 unbindObject(orb, "saliency", "CMapServers", objectName);
00620
00621 manager.stop();
00622 return 0;
00623 }
00624