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 "BeoSub/BeoSubSaliency.H"
00039 #include "Demo/DemoOpts.H"
00040
00041
00042 void *BeoSubSaliency_CMAP(void *c)
00043 {
00044 BeoSubSaliency *d = (BeoSubSaliency *)c;
00045 d->computeCMAP();
00046 return NULL;
00047 }
00048
00049
00050 BeoSubSaliency::BeoSubSaliency(OptionManager& mgr,
00051 const std::string& descrName,
00052 const std::string& tagName):
00053 ModelComponent(mgr, descrName, tagName),
00054 itsNumThreads(&OPT_SMTnumThreads, this)
00055 {
00056 MYLOGVERB = LOG_INFO;
00057
00058 win = Point2D<int>(IMAGEWIDTH/2, IMAGEHEIGHT/2);
00059 debugmode = false;
00060 hasRun = false;
00061
00062 pthread_mutex_init(&jobLock, NULL);
00063 pthread_mutex_init(&condLock, NULL);
00064 pthread_mutex_init(&mapLock, NULL);
00065 pthread_cond_init(&jobCond, NULL);
00066
00067
00068 worker = new pthread_t[itsNumThreads.getVal()];
00069 for (uint i = 0; i < itsNumThreads.getVal(); i ++){
00070 pthread_create(&worker[i], NULL, BeoSubSaliency_CMAP, (void *)this);
00071
00072
00073
00074 usleep(100000);
00075 }
00076
00077 }
00078
00079
00080 BeoSubSaliency::~BeoSubSaliency(){
00081
00082 pthread_cond_destroy(&jobCond);
00083 delete [] worker;
00084 }
00085
00086 Point2D<int> BeoSubSaliency::run(Image< PixRGB<byte> > img, bool debug){
00087
00088 debugmode = debug;
00089 dataReady = false;
00090 totalJobs = 0;
00091 jobsDone = 0;
00092 colima = img;
00093
00094 if(debugmode && !hasRun){
00095 hasRun = true;
00096 wini.reset( new XWindow(img.getDims(), -1, -1, "input window") );
00097 wini->setPosition(0, 0);
00098 wino.reset( new XWindow(img.getDims(), -1, -1, "output window") );
00099 wino->setPosition(370, 0);
00100 }
00101
00102 gotLum = false; gotRGBY = false;
00103
00104
00105 pthread_mutex_lock(&jobLock);
00106 jobQueue.clear();
00107
00108 jobQueue.push_back(jobData(INTENSITY, Gaussian5, IWEIGHT, 0.0F));
00109
00110 jobQueue.push_back(jobData(REDGREEN, Gaussian5, CWEIGHT, 0.0F));
00111
00112 jobQueue.push_back(jobData(SKINHUE, Gaussian5, SWEIGHT, 0.0F));
00113
00114
00115
00116
00117
00118
00119 jobQueue.push_back(jobData(FLICKER, Gaussian5, FWEIGHT, 0.0F));
00120
00121 jobQueue.push_back(jobData(BLUEYELLOW, Gaussian5, CWEIGHT, 0.0F));
00122
00123 totalJobs = jobQueue.size();
00124
00125 pthread_mutex_unlock(&jobLock);
00126
00127
00128 pthread_cond_broadcast(&jobCond);
00129
00130
00131 while(!dataReady){
00132 usleep(100);
00133 }
00134
00135
00136 findMax(outmap, winsm, maxval);
00137
00138 float minOut, maxOut;
00139
00140
00141 getMinMax(outmap, minOut, maxOut);
00142 LINFO("Min: %f Max: %f\n", minOut, maxOut);
00143
00144
00145 win.i = winsm.i << sml;
00146 win.i += int(((1<<(sml-1)) * float(rand()))/RAND_MAX);
00147 win.j = winsm.j << sml;
00148 win.j += int(((1<<(sml-1)) * float(rand()))/RAND_MAX);
00149
00150
00151 if(debugmode){
00152 Image<float> tmp = quickInterpolate(outmap, (1<<sml));
00153 inplaceNormalize(tmp, 0.0F, 255.0F);
00154 Image< PixRGB<byte> > temp = tmp;
00155 drawDisk(temp, win, 4, PixRGB<byte>(225, 225, 20));
00156 drawDisk(img, win, 4, PixRGB<byte>(225, 225, 20));
00157 wini->drawImage(img);
00158 wino->drawImage(temp);
00159 }
00160
00161 LINFO("The point of highest saliency is: %d, %d\n", win.i, win.j);
00162 outmap.clear();
00163 return win;
00164 }
00165
00166
00167
00168 void BeoSubSaliency::computeCMAP()
00169 {
00170
00171 while(true){
00172 jobData current(0, Gaussian5, 0.0F, 0.0F);
00173 bool jobsEmpty = true;
00174
00175
00176 pthread_mutex_lock(&jobLock);
00177 if(!jobQueue.empty()){
00178 current = jobQueue.front();
00179 jobQueue.pop_front();
00180 jobsEmpty = false;
00181 }
00182 else{
00183 jobsEmpty = true;
00184 }
00185
00186 if(!jobsEmpty){
00187
00188 Image<float> curImage;
00189
00190
00191 pthread_mutex_lock(&mapLock);
00192 switch(current.jobType)
00193 {
00194
00195 case REDGREEN:
00196 {
00197 if (gotRGBY == false){
00198 getRGBY(colima, r, g, b, y, byte(25)); gotRGBY = true;
00199 }
00200 curImage = r-g;
00201 }
00202 break;
00203 case BLUEYELLOW:
00204 {
00205 if (gotRGBY == false){
00206 getRGBY(colima, r, g, b, y, byte(25)); gotRGBY = true;
00207 }
00208 curImage = b-y;
00209 }
00210 break;
00211 case SKINHUE:
00212 {
00213 skinima = hueDistance(colima, COL_SKIN_MUR, COL_SKIN_MUG,
00214 COL_SKIN_SIGR, COL_SKIN_SIGG,
00215 COL_SKIN_RHO);
00216
00217 curImage = skinima;
00218 break;
00219 }
00220 case ORI0:
00221 {
00222 }
00223 case ORI45:
00224 {
00225 }
00226 case ORI90:
00227 {
00228 }
00229 case ORI135:
00230 {
00231 }
00232 case FLICKER:
00233 {
00234 if (gotLum == false){
00235 lum = Image<float>(luminance(colima)); gotLum = true;
00236 }
00237
00238 if (!previma.initialized()){
00239 previma = lum;
00240 curImage.resize(lum.getDims(), true);
00241 }
00242 else{
00243 curImage = lum - previma;
00244 previma = lum;
00245 }
00246 }
00247 break;
00248 case INTENSITY:
00249 {
00250 if (gotLum == false){
00251 lum = Image<float>(luminance(colima)); gotLum = true;
00252 }
00253 curImage = lum;
00254 }
00255 break;
00256 default:
00257 {
00258
00259 LERROR("Attempt to pass an invalid jobtype DENIED");
00260 curImage = lum;
00261 }
00262 break;
00263
00264
00265 }
00266 pthread_mutex_unlock(&mapLock);
00267
00268
00269 ImageSet<float> pyr = buildPyrGeneric(curImage, 0, maxdepth,
00270 current.ptyp,
00271 current.orientation);
00272
00273
00274 Image<float> cmap(pyr[sml].getDims(), ZEROS);
00275
00276
00277 for (int delta = delta_min; delta <= delta_max; delta ++)
00278 for (int lev = level_min; lev <= level_max; lev ++)
00279 {
00280 Image<float> tmp = centerSurround(pyr, lev, lev + delta, true);
00281 tmp = downSize(tmp, cmap.getWidth(), cmap.getHeight());
00282 inplaceAddBGnoise(tmp, 255.0);
00283 tmp = maxNormalize(tmp, MAXNORMMIN, MAXNORMMAX, normtyp);
00284 cmap += tmp;
00285 }
00286
00287 inplaceAddBGnoise(cmap, 25.0F);
00288
00289 if (normtyp == VCXNORM_MAXNORM)
00290 cmap = maxNormalize(cmap, MAXNORMMIN, MAXNORMMAX, normtyp);
00291 else
00292 cmap = maxNormalize(cmap, 0.0f, 0.0f, normtyp);
00293
00294
00295 if (current.weight != 1.0F) cmap *= current.weight;
00296
00297
00298 pthread_mutex_lock(&mapLock);
00299
00300
00301
00302
00303
00304
00305 if (outmap.initialized()){
00306 outmap += cmap;
00307 }
00308 else{
00309 outmap = cmap;
00310 }
00311
00312
00313
00314 jobsDone++;
00315 pthread_mutex_unlock(&mapLock);
00316
00317 }
00318 else{
00319
00320
00321 if(jobsDone >= totalJobs){
00322 dataReady = true;
00323 }
00324
00325 pthread_mutex_unlock(&jobLock);
00326
00327 pthread_cond_wait(&jobCond, &condLock);
00328
00329 pthread_mutex_unlock(&condLock);
00330
00331 pthread_mutex_lock(&jobLock);
00332
00333 }
00334 pthread_mutex_unlock(&jobLock);
00335 }
00336 return;
00337 }
00338
00339
00340
00341
00342
00343