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 #ifndef SURPRISE_CONTROL_C_DEFINED
00039 #define SURPRISE_CONTROL_C_DEFINED
00040
00041 #include "Surprise/SurpriseControl.H"
00042
00043 #include <typeinfo>
00044 #include <climits>
00045 #include <cfloat>
00046
00047
00048
00049 template <class PIXTYPE, class BETATYPE, class FLOAT>
00050 SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SurpriseControl(const ushort sizeX,
00051 const ushort sizeY)
00052 {
00053 LINFO("Creating SurpriseControl Object");
00054
00055
00056 SCinit(sizeX,sizeY);
00057 SCuseMaxLevel(false);
00058
00059 if(typeid(BETATYPE).name() != typeid(itsHyper).name())
00060 {
00061 LFATAL("Run time type error. Type: %s is not supported",
00062 typeid(BETATYPE).name());
00063 }
00064 }
00065
00066
00067
00068 template <class PIXTYPE, class BETATYPE, class FLOAT>
00069 SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SurpriseControl()
00070 {
00071 LINFO("Creating SurpriseControl Object NOTE: Call init()");
00072
00073 if(typeid(BETATYPE).name() != typeid(itsHyper).name())
00074 {
00075 LFATAL("Run time type error. Type: %s is not supported",
00076 typeid(BETATYPE).name());
00077 }
00078 }
00079
00080
00081
00082 template <class PIXTYPE, class BETATYPE, class FLOAT>
00083 SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::~SurpriseControl()
00084 {}
00085
00086
00087
00088 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
00089 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCuseMaxLevel(const bool useML)
00090 {
00091 LINFO("Setting itsUseMaxLevel");
00092 itsUseMaxLevel = useML;
00093 }
00094
00095
00096 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
00097 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCuseTemporal(const bool useTMP)
00098 {
00099 LINFO("Setting itsUseTemporal");
00100 itsUseTemporal = useTMP;
00101 }
00102
00103
00104 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
00105 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>:: SCnormalizeBiasWithScale(
00106 const bool useNBS)
00107 {
00108 LINFO("Setting itsNormalizeBiasWithScale");
00109 itsNormalizeBiasWithScale = useNBS;
00110 }
00111
00112
00113 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
00114 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCsetMasterConspicBias(
00115 const FLOAT bias)
00116 {
00117 itsMasterConspicBias = bias;
00118 }
00119
00120
00121 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
00122 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCsetConspicBias(
00123 const FLOAT chan,
00124 const int chan_enum)
00125 {
00126
00127 itsConspicMapBias[chan_enum] = chan;
00128 itsUseConspicMap[chan_enum] = true;
00129 }
00130
00131 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
00132 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCsetMyScale(const ushort scale)
00133 {
00134 itsScale = scale;
00135 }
00136
00137
00138
00139 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
00140 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCsetAxisBias(const FLOAT X,
00141 const FLOAT Y,
00142 const FLOAT Z)
00143 {
00144 itsXBias = X; itsYBias = Y; itsZBias = Z;
00145 }
00146
00147
00148 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
00149 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCsetH2SVBias(const FLOAT H1,
00150 const FLOAT H2,
00151 const FLOAT S,
00152 const FLOAT V)
00153 {
00154 itsH1Bias = H1; itsH2Bias = H2; itsSBias = S; itsVBias = V;
00155 }
00156
00157
00158
00159 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
00160 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCinit(const ushort sizeX,
00161 const ushort sizeY)
00162 {
00163 LINFO("INIT: image size %d x %d",sizeX,sizeY);
00164
00165 for(ushort i = 0; i < SC_MAX_CHANNELS; i++)
00166 {
00167 itsConspicMapBias[i] = 1.0F;
00168 itsUseConspicMap[i] = false;
00169 }
00170
00171 itsIterCounter = 0;
00172 itsScale = 0;
00173
00174 itsXBias = 1.0F; itsYBias = 1.0F; itsZBias = 1.0F;
00175
00176 itsLambda = 0.1;
00177 itsInitBuffer = false;
00178 itsUseCorrMatrixSet = false;
00179 itsUseBayesWeightImage = false;
00180 itsUseMaskImage = false;
00181 itsUseTargetFrame = false;
00182 itsUseTemporal = true;
00183 itsBufferFull = false;
00184 itsNormalizeBiasWithScale = false;
00185 itsImageSizeX = sizeX;
00186 itsImageSizeY = sizeY;
00187
00188 itsTargetFrame = 0;
00189
00190 itsInImage.resize(sizeX,sizeY);
00191 itsOutImage.resize(sizeX,sizeY);
00192 itsFinalImage.resize(sizeX,sizeY);
00193 itsLocalBiasH1.resize(sizeX,sizeY);
00194 itsLocalBiasH2.resize(sizeX,sizeY);
00195 itsLocalBiasS.resize(sizeX,sizeY);
00196 itsLocalBiasV.resize(sizeX,sizeY);
00197 itsSmallSaliency.resize(sizeX,sizeY);
00198 BETATYPE blank(0.0F);
00199 PIXTYPE blank2(0.0F);
00200
00201 Image<BETATYPE> initBeta; initBeta.resize(sizeX,sizeY);
00202 typename Image<BETATYPE>::iterator betaImageItr = initBeta.beginw();
00203 Image<PIXTYPE> tempImage;
00204 tempImage.resize(sizeX,sizeY);
00205 typename Image<PIXTYPE>::iterator tempImageItr = tempImage.beginw();
00206 while(betaImageItr != initBeta.endw())
00207 {
00208 *betaImageItr = blank;
00209 *tempImageItr = blank2;
00210 ++betaImageItr; ++tempImageItr;
00211 }
00212
00213 itsBetaImage.push_front(initBeta);
00214
00215
00216
00217 itsInterImage.resize(2,tempImage);
00218 }
00219
00220
00221
00222 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
00223 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCsetLambda(const FLOAT lambda)
00224 {
00225 itsLambda = lambda;
00226 }
00227
00228
00229
00230 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
00231 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCsetTargetFrame(const uint frame)
00232 {
00233 itsTargetFrame = frame;
00234 itsUseTargetFrame = true;
00235 }
00236
00237
00238
00239
00240
00241 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
00242 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCsetOriginalImageWeight(
00243 const FLOAT origImageWeight)
00244 {
00245 itsOriginalImageWeight = origImageWeight;
00246 }
00247
00248
00249
00250 template <class PIXTYPE, class BETATYPE, class FLOAT>
00251 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCcreateAndersonSepFilters(
00252 const ushort size)
00253 {
00254 const ushort basesize = 5;
00255
00256 if(size%basesize != 0)
00257 LFATAL("This kernel size must be evenly divisable by 5 got %d",size);
00258
00259 const FLOAT anderson[basesize] = {1.0/16.0, 4.0/16.0, 6.0/16.0,
00260 4.0/16.0, 1.0/16.0};
00261 for(ushort i = 0; i < basesize; i++)
00262 {
00263 LINFO("%f",anderson[i]);
00264 }
00265 const short div = size/basesize;
00266
00267 bool evensize;
00268
00269 if(size%2 == 0)
00270 {
00271 evensize = true;
00272 itsKernelSizeX = size + 1;
00273 itsKernelSizeY = size + 1;
00274 }
00275 else
00276 {
00277 itsKernelSizeX = size;
00278 itsKernelSizeY = size;
00279 evensize = false;
00280 }
00281 itsKernelSizeZ = basesize;
00282
00283 itsKalmanKernelX.resize(itsKernelSizeX,0.0F);
00284 itsKalmanKernelY.resize(itsKernelSizeY,0.0F);
00285 itsKalmanKernelZ.resize(itsKernelSizeZ,0.0F);
00286
00287 const FLOAT centerX = floor((FLOAT)itsKernelSizeX/2.0F);
00288
00289 ushort offset = 0;
00290 LINFO("Kernel (Anderson Variant) size %d",itsKernelSizeX);
00291 for(ushort i = 0; i < itsKernelSizeX; i++)
00292 {
00293 if((i < centerX) || (evensize == false))
00294 {
00295 if((i%div == 0) && (i != 0))
00296 offset++;
00297 }
00298 else
00299 {
00300 if((i - 1)%div == 0)
00301 offset++;
00302 }
00303
00304 itsKalmanKernelX[i] = anderson[offset];
00305 itsKalmanKernelY[i] = anderson[offset];
00306 std::cerr << i << " : " << itsKalmanKernelX[i] << "\n";
00307 }
00308
00309 for(ushort i = 0; i < itsKernelSizeZ; i++)
00310 {
00311 itsKalmanKernelZ[i] = anderson[i];
00312 }
00313
00314 itsImageSizeZ = itsKernelSizeZ;
00315 itsTemporalOffset = (ushort)floor(itsKernelSizeZ/2.0);
00316 }
00317
00318
00319 template <class PIXTYPE, class BETATYPE, class FLOAT>
00320 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCcreateSepFilters(
00321 const FLOAT spatSigma,
00322 const FLOAT tempSigma,
00323 const FLOAT stdDevSize)
00324 {
00325 LINFO("ASAC SETTING UP KERNELS");
00326
00327 ushort rs1 = (ushort)ceil(spatSigma*stdDevSize*2.0F);
00328 ushort rs2 = (ushort)floor(spatSigma*stdDevSize*2.0F);
00329
00330 if(rs1%2 == 0)
00331 {
00332 if(rs2%2 == 0)
00333 {
00334 itsKernelSizeX = rs2 + 1;
00335 itsKernelSizeY = rs2 + 1;
00336 }
00337 else
00338 {
00339 itsKernelSizeX = rs2;
00340 itsKernelSizeY = rs2;
00341 }
00342 }
00343 else
00344 {
00345 itsKernelSizeX = rs1;
00346 itsKernelSizeY = rs1;
00347 }
00348 itsKalmanKernelX.resize(itsKernelSizeX,0.0F);
00349 itsKalmanKernelY.resize(itsKernelSizeY,0.0F);
00350
00351 rs1 = (ushort)ceil((tempSigma*stdDevSize*2.0F));
00352 rs2 = (ushort)floor((tempSigma*stdDevSize*2.0F));
00353
00354 if(rs1%2 == 0)
00355 {
00356 if(rs2%2 == 0)
00357 {
00358 itsKernelSizeZ = rs2 + 1;
00359 }
00360 else
00361 {
00362 itsKernelSizeZ = rs2;
00363 }
00364 }
00365 else
00366 {
00367 itsKernelSizeZ = rs1;
00368 }
00369 itsKalmanKernelZ.resize(itsKernelSizeZ,0.0F);
00370
00371 itsImageSizeZ = itsKernelSizeZ;
00372
00373
00374
00375 const FLOAT centerX = floor((FLOAT)itsKernelSizeX/2.0F);
00376 const FLOAT centerY = floor((FLOAT)itsKernelSizeY/2.0F);
00377 const FLOAT centerZ = floor((FLOAT)itsKernelSizeZ/2.0F);
00378
00379 FLOAT gmod = 1.0F/sqrt(2.0F*M_PI*pow(spatSigma,2));
00380
00381 LINFO("Kernel X size %d",itsKernelSizeX);
00382 for(ushort i = 0; i < itsKernelSizeX; i++)
00383 {
00384 const FLOAT dist = pow((i - centerX),2);
00385 itsKalmanKernelX[i] =
00386 (gmod*exp((-1.0F*dist)/pow(2*spatSigma,2)));
00387 std::cerr << i << " : " << itsKalmanKernelX[i] << "\n";
00388 }
00389 LINFO("Kernel Y size %d",itsKernelSizeY);
00390 for(ushort i = 0; i < itsKernelSizeY; i++)
00391 {
00392 const FLOAT dist = pow((i - centerY),2);
00393 itsKalmanKernelY[i] =
00394 (gmod*exp((-1.0F*dist)/pow(2*spatSigma,2)));
00395 std::cerr << i << " : " << itsKalmanKernelY[i] << "\n";
00396 }
00397
00398 gmod = 1.0F/sqrt(2.0F*M_PI*pow(tempSigma,2));
00399 LINFO("Kernel Z size %d",itsKernelSizeZ);
00400 for(ushort i = 0; i < itsKernelSizeZ; i++)
00401 {
00402 const FLOAT dist = pow((i - centerZ),2);
00403 itsKalmanKernelZ[i] =
00404 (gmod*exp((-1.0F*dist)/pow(2*tempSigma,2)));
00405 std::cerr << i << " : " << itsKalmanKernelZ[i] << "\n";
00406 }
00407
00408 itsTemporalOffset = (ushort)floor(itsKernelSizeZ/2.0);
00409 }
00410
00411
00412 template <class PIXTYPE, class BETATYPE, class FLOAT>
00413 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCfindConvolutionEndPoints()
00414 {
00415 LINFO("SETTING UP CONVOLUTION END POINTS");
00416
00417 itsXStart.resize(itsImageSizeX,itsImageSizeY);
00418 itsYStart.resize(itsImageSizeX,itsImageSizeY);
00419 itsZStart.resize(itsImageSizeX,itsImageSizeY);
00420 itsXStop.resize( itsImageSizeX,itsImageSizeY);
00421 itsYStop.resize( itsImageSizeX,itsImageSizeY);
00422 itsZStop.resize( itsImageSizeX,itsImageSizeY);
00423 itsKXStart.resize(itsImageSizeX,itsImageSizeY);
00424 itsKYStart.resize(itsImageSizeX,itsImageSizeY);
00425 itsKZStart.resize(itsImageSizeX,itsImageSizeY);
00426
00427 Image<ushort>::iterator itsZStartItr = itsZStart.beginw();
00428 Image<ushort>::iterator itsZStopItr = itsZStop.beginw();
00429 Image<ushort>::iterator itsKZStartItr = itsKZStart.beginw();
00430
00431 Image<ushort>::iterator itsYStartItr = itsYStart.beginw();
00432 Image<ushort>::iterator itsYStopItr = itsYStop.beginw();
00433 Image<ushort>::iterator itsKYStartItr = itsKYStart.beginw();
00434
00435 Image<ushort>::iterator itsXStartItr = itsXStart.beginw();
00436 Image<ushort>::iterator itsXStopItr = itsXStop.beginw();
00437 Image<ushort>::iterator itsKXStartItr = itsKXStart.beginw();
00438
00439 for(ushort y = 0; y < itsImageSizeY; y++)
00440 {
00441 for(ushort x = 0; x < itsImageSizeX; x++)
00442 {
00443
00444
00445
00446 *itsKZStartItr = 0;
00447 *itsZStartItr = 0;
00448 *itsZStopItr = itsKernelSizeZ;
00449
00450 const ushort yhalf = (ushort)floor((FLOAT)itsKernelSizeY/2.0F);
00451 const ushort yend = itsImageSizeY - yhalf;
00452 if(y < yhalf + 1)
00453 {
00454 *itsYStartItr = 0;
00455 *itsKYStartItr = yhalf - y;
00456 *itsYStopItr = y + yhalf;
00457 }
00458 else if(y > yend)
00459 {
00460 *itsYStartItr = y - yhalf;
00461 *itsKYStartItr = 0;
00462 *itsYStopItr = itsImageSizeY;
00463 }
00464 else
00465 {
00466 *itsYStartItr = y - yhalf;
00467 *itsKYStartItr = 0;
00468 *itsYStopItr = y + yhalf;
00469 }
00470
00471 const ushort xhalf = (ushort)floor((FLOAT)itsKernelSizeX/2.0F);
00472 const ushort xend = itsImageSizeX - xhalf;
00473 if(x < xhalf + 1)
00474 {
00475 *itsXStartItr = 0;
00476 *itsKXStartItr = xhalf - x;
00477 *itsXStopItr = x + xhalf;
00478 }
00479 else if(x > xend)
00480 {
00481 *itsXStartItr = x - xhalf;
00482 *itsKXStartItr = 0;
00483 *itsXStopItr = itsImageSizeX;
00484 }
00485 else
00486 {
00487 *itsXStartItr = x - xhalf;
00488 *itsKXStartItr = 0;
00489 *itsXStopItr = x + xhalf;
00490 }
00491
00492 ++itsZStartItr; ++itsZStopItr; ++itsKZStartItr;
00493 ++itsYStartItr; ++itsYStopItr; ++itsKYStartItr;
00494 ++itsXStartItr; ++itsXStopItr; ++itsKXStartItr;
00495 }
00496 }
00497 }
00498
00499
00500
00501 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
00502 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCinputRawImage(
00503 const Image<PixRGB<FLOAT> >& rawImage)
00504 {
00505
00506
00507 if(rawImage.getHeight() != itsImageSizeY)
00508 {
00509 LINFO("Input raw image is not the correct size");
00510 LFATAL("Raw %d != sizeY %d",rawImage.getHeight(),itsImageSizeY);
00511 }
00512 if(rawImage.getWidth() != itsImageSizeX)
00513 {
00514 LINFO("Input raw image is not the correct size");
00515 LFATAL("Raw %d != sizeX %d",rawImage.getWidth(),itsImageSizeX);
00516 }
00517
00518 typename Image<PIXTYPE >::iterator inImageItr =
00519 itsInImage.beginw();
00520 typename Image<PixRGB<FLOAT> >::const_iterator rawImageItr =
00521 rawImage.begin();
00522
00523
00524 while(inImageItr != itsInImage.endw())
00525 {
00526 *inImageItr = PIXTYPE(*rawImageItr);
00527 ++inImageItr; ++rawImageItr;
00528 }
00529
00530 itsFrameBuffer.push_front(itsInImage);
00531 itsInitBuffer = true;
00532
00533
00534 if(itsFrameBuffer.size() > (unsigned)(itsImageSizeZ + 1))
00535 {
00536 itsFrameBuffer.pop_back();
00537 itsBufferFull = true;
00538 }
00539 }
00540
00541
00542
00543 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
00544 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCinputSalMap(
00545 const Image<FLOAT>& salMap)
00546 {
00547 if(itsInImage.getWidth() != salMap.getWidth())
00548 {
00549 LINFO("Saliency map is the wrong size or raw image not initalized");
00550 LFATAL("Sal Map Width %d != Raw Image Width %d",salMap.getWidth(),
00551 itsInImage.getWidth());
00552 }
00553 if(itsInImage.getHeight() != salMap.getHeight())
00554 {
00555 LINFO("Saliency map is the wrong size or raw image not initalized");
00556 LFATAL("Sal Map Height %d != Raw Image Height %d",salMap.getHeight(),
00557 itsInImage.getHeight());
00558 }
00559
00560
00561 itsSalMap = salMap/255.0F;
00562 }
00563
00564
00565
00566 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
00567 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCinputConspicMap(
00568 const Image<FLOAT>& cmap,
00569 const int cmap_enum)
00570 {
00571 if(itsUseConspicMap[cmap_enum] != true)
00572 {
00573 LINFO("Called to input %s image, but did not expect it",
00574 sc_channel_name[cmap_enum].c_str());
00575 LFATAL("Be sure to set the bias first!");
00576 }
00577 if(itsInImage.getWidth() != cmap.getWidth())
00578 {
00579 LINFO("Saliency map is the wrong size or raw image not initalized");
00580 LFATAL("Conspic Width %d != Raw Width %d",cmap.getWidth(),
00581 itsInImage.getWidth());
00582 }
00583 if(itsInImage.getHeight() != cmap.getHeight())
00584 {
00585 LINFO("Saliency map is the wrong size or raw image not initalized");
00586 LFATAL("Conspic Height %d != Raw Height %d",cmap.getHeight(),
00587 itsInImage.getHeight());
00588 }
00589
00590 itsConspicMap[cmap_enum] = cmap/255.0F;
00591 itsConspicMap[cmap_enum] = itsConspicMap[cmap_enum] *
00592 itsConspicMapBias[cmap_enum];
00593
00594 itsConspicMap[cmap_enum] = itsConspicMap[cmap_enum] * itsMasterConspicBias;
00595
00596
00597
00598 if(itsUseBayesWeightImage)
00599 {
00600 if(itsConspicMap[cmap_enum].getWidth() != itsBayesWeightImage.getWidth())
00601 LFATAL("Bayes image must be same width as conspicuity maps");
00602 if(itsConspicMap[cmap_enum].getHeight() != itsBayesWeightImage.getHeight())
00603 LFATAL("Bayes image must be same height as conspicuity maps");
00604
00605 typename Image<FLOAT>::iterator icmap = itsConspicMap[cmap_enum].beginw();
00606 typename Image<FLOAT>::const_iterator bayes = itsBayesWeightImage.begin();
00607 while(icmap != itsConspicMap[cmap_enum].endw())
00608 {
00609 *icmap = (*icmap) * (*bayes);
00610 ++icmap; ++bayes;
00611 }
00612 }
00613
00614 if(itsUseMaskImage)
00615 {
00616 if(itsConspicMap[cmap_enum].getWidth() != itsMaskImage.getWidth())
00617 LFATAL("Mask image must be same width as conspicuity maps");
00618 if(itsConspicMap[cmap_enum].getHeight() != itsMaskImage.getHeight())
00619 LFATAL("Mask image must be same height as conspicuity maps");
00620
00621 typename Image<FLOAT>::iterator icmap = itsConspicMap[cmap_enum].beginw();
00622 typename Image<FLOAT>::const_iterator mask = itsMaskImage.begin();
00623 while(icmap != itsConspicMap[cmap_enum].endw())
00624 {
00625 *icmap = (*icmap) * (*mask);
00626
00627 ++icmap; ++mask;
00628 }
00629 }
00630
00631 if(SC_DEBUG)
00632 {
00633 char name[100];
00634 sprintf(name,"debug-conspic-%d-%d-%d.png",itsScale,itsIterCounter,cmap_enum);
00635 std::string prefix = name;
00636 Image<PixRGB<FLOAT> > temp =
00637 normalizeScaleRainbow(itsConspicMap[cmap_enum],0,5);
00638 Raster::WriteRGB(temp, prefix);
00639 }
00640
00641 }
00642
00643
00644
00645 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
00646 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCinputBayesWeightImage(
00647 const Image<FLOAT> &bayesImage)
00648 {
00649 LINFO("INPUT Bayes Weight Image");
00650 itsUseBayesWeightImage = true;
00651 itsBayesWeightImage = bayesImage;
00652 }
00653
00654
00655 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
00656 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCinputMaskImage(
00657 const Image<FLOAT> &maskImage)
00658
00659 {
00660 FLOAT mi, ma;
00661 getMinMax(maskImage,mi,ma);
00662 if(mi < 0)
00663 {
00664 LINFO("Mask Image value too low = %f",mi);
00665 LFATAL("Mask Image pixel values must be from 0 to 1");
00666 }
00667 if(ma > 1)
00668 {
00669 LINFO("Mask Image value too high = %f",ma);
00670 LFATAL("Mask Image pixel values must be from 0 to 1");
00671 }
00672 LINFO("INPUT independant mask image");
00673 itsUseMaskImage = true;
00674 itsMaskImage = maskImage;
00675 }
00676
00677
00678 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
00679 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCcomputeNewBeta()
00680 {
00681
00682
00683
00684
00685
00686
00687 Image<BETATYPE> betaImage; betaImage.resize(itsImageSizeX,itsImageSizeY);
00688 for(ushort i = 0; i < SC_MAX_CHANNELS; i++)
00689 {
00690 if(itsUseConspicMap[i])
00691 {
00692 typename Image<BETATYPE>::iterator betaImageItr;
00693 typename Image<FLOAT>::iterator consMapItr =
00694 itsConspicMap[i].beginw();
00695 typename Image<BETATYPE>::const_iterator betaImageOldItr =
00696 itsBetaImage[0].begin();
00697 typename Image<FLOAT>::const_iterator itsBayesWeightItr =
00698 itsBayesWeightImage.begin();
00699
00700 for(betaImageItr = betaImage.beginw();
00701 betaImageItr != betaImage.endw();
00702 ++betaImageItr, ++consMapItr,
00703 ++itsBayesWeightItr, ++betaImageOldItr)
00704 {
00705 if(itsUseBayesWeightImage)
00706 {
00707 *consMapItr = *consMapItr * (*itsBayesWeightItr);
00708 }
00709
00710 betaImageItr->p[i] =
00711 (betaImageOldItr->p[i] * itsLambda + *consMapItr)/
00712 (1 + 1 * itsLambda);
00713 }
00714
00715 if(SC_DEBUG)
00716 {
00717 Image<FLOAT> ftemp; ftemp.resize(betaImage.getWidth(),
00718 betaImage.getHeight());
00719
00720 typename Image<FLOAT>::iterator itmp = ftemp.beginw();
00721
00722 for(betaImageItr = betaImage.beginw();
00723 betaImageItr != betaImage.endw();
00724 ++betaImageItr, ++itmp)
00725 *itmp = betaImageItr->p[i];
00726
00727 char name[100];
00728 sprintf(name,"debug-beta-%d-%d-%d.png",itsScale,itsIterCounter,i);
00729 std::string prefix = name;
00730 Image<PixRGB<FLOAT> > temp =
00731 normalizeScaleRainbow(ftemp,0,5);
00732 Raster::WriteRGB(temp, prefix);
00733 }
00734 }
00735 }
00736 itsBetaImage.push_front(betaImage);
00737
00738
00739 if(itsBetaImage.size() > (unsigned)(itsImageSizeZ + 1))
00740 itsBetaImage.pop_back();
00741 }
00742
00743
00744
00745 template <class PIXTYPE, class BETATYPE, class FLOAT>
00746 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCprocessFrameSeperable()
00747 {
00748 LINFO("PROCESSING FRAME Kernel Size X - %d Y - %d Z - %d",
00749 itsKernelSizeX,
00750 itsKernelSizeY,
00751 itsKernelSizeZ);
00752
00753 typename Image<PixRGB<FLOAT> >::iterator finalImageItr =
00754 itsFinalImage.beginw();
00755
00756
00757
00758
00759
00760
00761 SCcomputeNewBeta();
00762
00763 LINFO("Buffer %"ZU" ksize %d",itsFrameBuffer.size(),itsKernelSizeZ);
00764 if(itsFrameBuffer.size() > (uint)itsTemporalOffset)
00765 {
00766 itsOutputReady = true;
00767 itsFrameCurrent = &itsFrameBuffer[(uint)itsTemporalOffset];
00768 itsBetaCurrent = &itsBetaImage[(uint)itsTemporalOffset];
00769
00770 SCcomputeLocalBias();
00771
00772 if(itsUseTemporal)
00773 {
00774 LINFO("Convolving image x,y,z");
00775 SCseperateConvXYZ();
00776 }
00777 else
00778 {
00779 LINFO("Convolving image x,y");
00780 SCseperateConvXY();
00781 }
00782
00783 LINFO("FINISHING image");
00784 typename Image<PIXTYPE >::const_iterator outImageItr = itsOutImage.begin();
00785 for(finalImageItr = itsFinalImage.beginw();
00786 finalImageItr != itsFinalImage.endw();
00787 ++finalImageItr, ++outImageItr)
00788 {
00789 *finalImageItr = PixRGB<FLOAT>(*outImageItr);
00790 }
00791 LINFO("DONE");
00792 }
00793 else
00794 {
00795 LINFO("FRAME BUFFER NOT YET HALF FULL");
00796 itsOutputReady = false;
00797 for(finalImageItr = itsFinalImage.beginw();
00798 finalImageItr != itsFinalImage.endw();
00799 ++finalImageItr)
00800 {
00801 *finalImageItr = PixRGB<FLOAT>(0,0,0);
00802 }
00803 }
00804 itsIterCounter++;
00805 }
00806
00807
00808 template <class PIXTYPE, class BETATYPE, class FLOAT>
00809 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCcomputeLocalBias()
00810 {
00811
00812 if(!(itsUseConspicMap[SC_DR0] == itsUseConspicMap[SC_DR1] &&
00813 itsUseConspicMap[SC_DR0] == itsUseConspicMap[SC_DR2] &&
00814 itsUseConspicMap[SC_DR0] == itsUseConspicMap[SC_DR3]))
00815 LFATAL("You must use all four direction channels or none!");
00816
00817 if(!(itsUseConspicMap[SC_GA0] == itsUseConspicMap[SC_GA1] &&
00818 itsUseConspicMap[SC_GA0] == itsUseConspicMap[SC_GA2] &&
00819 itsUseConspicMap[SC_GA0] == itsUseConspicMap[SC_GA3]))
00820 LFATAL("You must use all four orientation channels or none!");
00821
00822 if(!(itsUseConspicMap[SC_H1] == itsUseConspicMap[SC_H2] &&
00823 itsUseConspicMap[SC_H1] == itsUseConspicMap[SC_HS] &&
00824 itsUseConspicMap[SC_H1] == itsUseConspicMap[SC_HV]))
00825 LFATAL("You must use all four H2SV channels or none!");
00826
00827 if(!(itsUseConspicMap[SC_RG] == itsUseConspicMap[SC_BY]))
00828 LFATAL("You must use both RG and BY channels or none!");
00829 Image<bool>::iterator iSmallS;
00830
00831
00832 iSmallS = itsSmallSaliency.beginw();
00833 for(typename Image<BETATYPE>::const_iterator betaImageItr =
00834 itsBetaCurrent->begin(); betaImageItr != itsBetaCurrent->end();
00835 ++betaImageItr, ++iSmallS)
00836 {
00837
00838
00839 *iSmallS = true;
00840
00841 for(ushort i = 0; i < SC_MAX_CHANNELS; i++)
00842 {
00843 if(betaImageItr->p[i] > SMALL_SALIENCY)
00844 *iSmallS = false;
00845 }
00846 }
00847
00848
00849 typename Image<FLOAT>::iterator iBiasH1 = itsLocalBiasH1.beginw();
00850 typename Image<FLOAT>::iterator iBiasH2 = itsLocalBiasH2.beginw();
00851 typename Image<FLOAT>::iterator iBiasS = itsLocalBiasS.beginw();
00852 typename Image<FLOAT>::iterator iBiasV = itsLocalBiasV.beginw();
00853
00854 for(typename Image<BETATYPE>::const_iterator betaImageItr =
00855 itsBetaCurrent->begin(); betaImageItr != itsBetaCurrent->end();
00856 ++betaImageItr,
00857 ++iBiasH1, ++iBiasH2, ++iBiasS, ++iBiasV, ++iSmallS)
00858 {
00859 *iBiasH1 = 0; *iBiasH2 = 0; *iBiasS = 0; *iBiasV = 0;
00860 }
00861
00862
00863 if(itsUseMaxLevel)
00864 {
00865
00866 iBiasH1 = itsLocalBiasH1.beginw();
00867 iBiasH2 = itsLocalBiasH2.beginw();
00868 iBiasS = itsLocalBiasS.beginw();
00869 iBiasV = itsLocalBiasV.beginw();
00870
00871 for(typename Image<BETATYPE>::const_iterator betaImageItr =
00872 itsBetaCurrent->begin(); betaImageItr != itsBetaCurrent->end();
00873 ++betaImageItr,
00874 ++iBiasH1, ++iBiasH2, ++iBiasS, ++iBiasV)
00875 {
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885 const FLOAT *betaImg = betaImageItr->p;
00886
00887 if(itsUseConspicMap[SC_H1])
00888 {
00889 *iBiasH1 = betaImg[SC_H1];
00890 *iBiasH2 = betaImg[SC_H2];
00891 *iBiasS = betaImg[SC_HS];
00892 *iBiasV = betaImg[SC_HV];
00893 }
00894 else
00895 {
00896 if(itsUseConspicMap[SC_BY])
00897 {
00898 if(betaImageItr->p[SC_BY] > betaImageItr->p[SC_RG])
00899 {
00900 *iBiasH1 = betaImg[SC_BY];
00901 *iBiasH2 = betaImg[SC_BY];
00902 *iBiasS = betaImg[SC_BY];
00903 }
00904 else
00905 {
00906 *iBiasH1 = betaImg[SC_RG];
00907 *iBiasH2 = betaImg[SC_RG];
00908 *iBiasS = betaImg[SC_RG];
00909 }
00910 }
00911 }
00912
00913 FLOAT newVal = 0;
00914 for(ushort i = 0; i < SC_MAX_CHANNELS; i++)
00915 {
00916 if(betaImg[i] > newVal && itsUseConspicMap[i])
00917 newVal = betaImg[i];
00918 }
00919 *iBiasV = newVal;
00920 }
00921 }
00922 else
00923 {
00924 iBiasH1 = itsLocalBiasH1.beginw();
00925 iBiasH2 = itsLocalBiasH2.beginw();
00926 iBiasS = itsLocalBiasS.beginw();
00927 iBiasV = itsLocalBiasV.beginw();
00928
00929 for(typename Image<BETATYPE>::const_iterator betaImageItr =
00930 itsBetaCurrent->begin(); betaImageItr != itsBetaCurrent->end();
00931 ++betaImageItr,
00932 ++iBiasH1, ++iBiasH2, ++iBiasS, ++iBiasV)
00933 {
00934
00935
00936
00937
00938
00939
00940
00941 const FLOAT *betaImg = betaImageItr->p;
00942
00943
00944 if(itsUseConspicMap[SC_H1])
00945 {
00946 *iBiasH1 = betaImg[SC_H1];
00947 *iBiasH2 = betaImg[SC_H2];
00948 *iBiasS = betaImg[SC_HS];
00949 *iBiasV = betaImg[SC_HV];
00950 }
00951 else
00952 {
00953 if(itsUseConspicMap[SC_BY])
00954 {
00955 *iBiasH1 = (betaImg[SC_BY] + betaImg[SC_RG]);
00956 *iBiasH2 = (betaImg[SC_BY] + betaImg[SC_RG]);
00957 *iBiasS = (betaImg[SC_BY] + betaImg[SC_RG]);
00958 *iBiasV = (betaImg[SC_BY] + betaImg[SC_RG]);
00959 }
00960
00961 if(itsUseConspicMap[SC_IN])
00962 *iBiasV += betaImg[SC_IN];
00963 }
00964
00965 if(itsUseConspicMap[SC_FL])
00966 *iBiasV += betaImg[SC_FL];
00967 if(itsUseConspicMap[SC_DR0])
00968 *iBiasV += betaImg[SC_DR0] + betaImg[SC_DR1] +
00969 betaImg[SC_DR2] + betaImg[SC_DR3];
00970 if(itsUseConspicMap[SC_GA0])
00971 *iBiasV += betaImg[SC_GA0] + betaImg[SC_GA1] +
00972 betaImg[SC_GA2] + betaImg[SC_GA3];
00973 }
00974 }
00975
00976 if(itsNormalizeBiasWithScale)
00977 {
00978 FLOAT miH1, maH1, miH2, maH2, miS, maS, miV, maV;
00979 FLOAT fmaxH1, fmaxH2, fmaxS, fmaxV;
00980 getMinMax(itsLocalBiasH1,miH1,maH1);
00981 getMinMax(itsLocalBiasH2,miH2,maH2);
00982 getMinMax(itsLocalBiasS, miS, maS);
00983 getMinMax(itsLocalBiasV, miV, maV);
00984
00985
00986
00987 if((maH1 > maH2) && (maH1 > maS) && (maH1 > maV))
00988 {
00989 const FLOAT adj = 1.0 / maH1;
00990 fmaxH1 = 1.0;
00991 fmaxH2 = maH2 * adj;
00992 fmaxS = maS * adj;
00993 fmaxV = maV * adj;
00994 }
00995 else if((maH2 > maS) && (maH2 > maV))
00996 {
00997 const FLOAT adj = 1.0 / maH2;
00998 fmaxH2 = 1.0;
00999 fmaxH1 = maH1 * adj;
01000 fmaxS = maS * adj;
01001 fmaxV = maV * adj;
01002 }
01003 else if(maS > maV)
01004 {
01005 const FLOAT adj = 1.0 / maS;
01006 fmaxS = 1.0;
01007 fmaxH1 = maH1 * adj;
01008 fmaxH2 = maH2 * adj;
01009 fmaxV = maV * adj;
01010 }
01011 else
01012 {
01013 const FLOAT adj = 1.0 / maV;
01014 fmaxV = 1.0;
01015 fmaxH1 = maH1 * adj;
01016 fmaxH2 = maH2 * adj;
01017 fmaxS = maS * adj;
01018 }
01019
01020 for(iBiasH1 = itsLocalBiasH1.beginw(); iBiasH1 != itsLocalBiasH1.endw();
01021 ++iBiasH1)
01022 {
01023 *iBiasH1 = ((*iBiasH1 - miH1) / (maH1 - miH1)) * fmaxH1;
01024 }
01025
01026 for(iBiasH2 = itsLocalBiasH2.beginw(); iBiasH2 != itsLocalBiasH2.endw();
01027 ++iBiasH2)
01028 {
01029 *iBiasH2 = ((*iBiasH2 - miH2) / (maH2 - miH2)) * fmaxH2;
01030 }
01031
01032 for(iBiasS = itsLocalBiasS.beginw(); iBiasS != itsLocalBiasS.endw();
01033 ++iBiasS)
01034 {
01035 *iBiasS = ((*iBiasS - miS) / (maS - miS)) * fmaxS;
01036 }
01037
01038 for(iBiasV = itsLocalBiasV.beginw(); iBiasV != itsLocalBiasV.endw();
01039 ++iBiasV)
01040 {
01041 *iBiasV = ((*iBiasV - miV) / (maV - miV)) * fmaxV;
01042 }
01043 }
01044
01045
01046
01047 for(iBiasH1 = itsLocalBiasH1.beginw(); iBiasH1 != itsLocalBiasH1.endw();
01048 ++iBiasH1)
01049 {
01050 *iBiasH1 = itsH1Bias * *iBiasH1;
01051 }
01052
01053 for(iBiasH2 = itsLocalBiasH2.beginw(); iBiasH2 != itsLocalBiasH2.endw();
01054 ++iBiasH2)
01055 {
01056 *iBiasH2 = itsH2Bias * *iBiasH2;
01057 }
01058
01059 for(iBiasS = itsLocalBiasS.beginw(); iBiasS != itsLocalBiasS.endw();
01060 ++iBiasS)
01061 {
01062 *iBiasS = itsSBias * *iBiasS;
01063 }
01064
01065 for(iBiasV = itsLocalBiasV.beginw(); iBiasV != itsLocalBiasV.endw();
01066 ++iBiasV)
01067 {
01068 *iBiasV = itsVBias * *iBiasV;
01069 }
01070
01071 if(SC_DEBUG)
01072 {
01073 char name[100];
01074 sprintf(name,"debug-biasParts-H1-%d-%d.png",itsScale,itsIterCounter);
01075 std::string prefix = name;
01076 Image<PixRGB<FLOAT> > temp =
01077 normalizeScaleRainbow(itsLocalBiasH1,0,5);
01078 Raster::WriteRGB(temp, prefix);
01079
01080 sprintf(name,"debug-biasParts-H2-%d-%d.png",itsScale,itsIterCounter);
01081 prefix = name;
01082 temp = normalizeScaleRainbow(itsLocalBiasH2,0,5);
01083 Raster::WriteRGB(temp, prefix);
01084
01085 sprintf(name,"debug-biasParts-S-%d-%d.png",itsScale,itsIterCounter);
01086 prefix = name;
01087 temp = normalizeScaleRainbow(itsLocalBiasS,0,5);
01088 Raster::WriteRGB(temp, prefix);
01089
01090 sprintf(name,"debug-biasParts-V-%d-%d.png",itsScale,itsIterCounter);
01091 prefix = name;
01092 temp = normalizeScaleRainbow(itsLocalBiasV,0,5);
01093 Raster::WriteRGB(temp, prefix);
01094 }
01095 }
01096
01097
01098
01099 template <class PIXTYPE, class BETATYPE, class FLOAT>
01100 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCseperateConvXYZ()
01101 {
01102 SCseperateConv('z');
01103 SCseperateConv('y');
01104 SCseperateConv('x');
01105 }
01106
01107
01108
01109 template <class PIXTYPE, class BETATYPE, class FLOAT>
01110 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCseperateConvXY()
01111 {
01112
01113
01114 itsInterImage[0] = *itsFrameCurrent;
01115 SCseperateConv('y');
01116 SCseperateConv('x');
01117 }
01118
01119
01120
01121 template <class PIXTYPE, class BETATYPE, class FLOAT>
01122 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCseperateConv(const char axis)
01123 {
01124 const typename std::deque<Image<PIXTYPE > >::const_iterator
01125 frameBufferBegin = itsFrameBuffer.begin();
01126
01127
01128
01129 typename Image<PIXTYPE >::iterator outImageItr;
01130 typename Image<PIXTYPE >::iterator outImageBegin;
01131 typename Image<PIXTYPE >::iterator outImageEnd;
01132 typename Image<PIXTYPE >::const_iterator inImageItr;
01133 typename Image<PIXTYPE >::const_iterator inImageTrueItr;
01134
01135 Image<ushort>::const_iterator itsStartItr;
01136 Image<ushort>::const_iterator itsStopItr;
01137 Image<ushort>::const_iterator itsKStartItr;
01138
01139 typename std::deque<Image<PIXTYPE > >::const_iterator frameBufferItr;
01140 typename std::vector<FLOAT>::const_iterator kalmanKernelbegin;
01141 FLOAT axisBias;
01142
01143 if(axis == 'z')
01144 {
01145
01146
01147
01148 inImageItr = itsFrameCurrent->begin();
01149 outImageBegin = itsInterImage[0].beginw();
01150 outImageEnd = itsInterImage[0].endw();
01151 itsStartItr = itsZStart.begin();
01152 itsStopItr = itsZStop.begin();
01153 itsKStartItr = itsKZStart.begin();
01154 kalmanKernelbegin = itsKalmanKernelZ.begin();
01155 axisBias = itsZBias;
01156 }
01157 else if(axis == 'y')
01158 {
01159
01160 inImageItr = itsInterImage[0].begin();
01161 outImageBegin = itsInterImage[1].beginw();
01162 outImageEnd = itsInterImage[1].endw();
01163 itsStartItr = itsYStart.begin();
01164 itsStopItr = itsYStop.begin();
01165 itsKStartItr = itsKYStart.begin();
01166 kalmanKernelbegin = itsKalmanKernelY.begin();
01167 axisBias = itsYBias;
01168 }
01169 else if(axis == 'x')
01170 {
01171 inImageItr = itsInterImage[1].begin();
01172 outImageBegin = itsOutImage.beginw();
01173 outImageEnd = itsOutImage.endw();
01174 itsStartItr = itsXStart.begin();
01175 itsStopItr = itsXStop.begin();
01176 itsKStartItr = itsKXStart.begin();
01177 kalmanKernelbegin = itsKalmanKernelX.begin();
01178 axisBias = itsXBias;
01179 }
01180 else
01181 {
01182 LINFO("Must use axis as z,x then y in that order");
01183 LFATAL("Unknown axis specified %c",axis);
01184
01185 inImageItr = itsInterImage[1].begin();
01186 outImageBegin = itsOutImage.beginw();
01187 outImageEnd = itsOutImage.endw();
01188 itsStartItr = itsXStart.begin();
01189 itsStopItr = itsXStop.begin();
01190 itsKStartItr = itsKXStart.begin();
01191 kalmanKernelbegin = itsKalmanKernelX.begin();
01192 axisBias = itsXBias;
01193 }
01194
01195
01196 for(outImageItr = outImageBegin; outImageItr != outImageEnd; ++outImageItr)
01197 {
01198 outImageItr->p[0] = 0.0F;
01199 outImageItr->p[1] = 0.0F;
01200 outImageItr->p[2] = 0.0F;
01201 outImageItr->p[3] = 0.0F;
01202 }
01203
01204 typename Image<FLOAT>::const_iterator iBiasH1 = itsLocalBiasH1.begin();
01205 typename Image<FLOAT>::const_iterator iBiasH2 = itsLocalBiasH2.begin();
01206 typename Image<FLOAT>::const_iterator iBiasS = itsLocalBiasS.begin();
01207 typename Image<FLOAT>::const_iterator iBiasV = itsLocalBiasV.begin();
01208
01209 inImageTrueItr = itsFrameCurrent->begin();
01210
01211
01212 int pos = 0;
01213 ushort Zstop = 0;
01214
01215 if(axis == 'z')
01216 {
01217 if(itsFrameBuffer.size() > itsKernelSizeZ)
01218 Zstop = itsKernelSizeZ;
01219 else
01220 Zstop = itsFrameBuffer.size();
01221 }
01222
01223 for(outImageItr = outImageBegin;
01224 outImageItr != outImageEnd; pos++,
01225 ++outImageItr, ++inImageItr,
01226 ++itsStartItr, ++itsStopItr, ++itsKStartItr, ++inImageTrueItr,
01227 ++iBiasH1, ++iBiasH2, ++iBiasS, ++iBiasV)
01228 {
01229
01230
01231 FLOAT npixH1 = 0.0F;
01232 FLOAT npixH2 = 0.0F;
01233 FLOAT npixS = 0.0F;
01234 FLOAT npixV = 0.0F;
01235
01236 const FLOAT H1bias = *iBiasH1 * axisBias;
01237 const FLOAT H2bias = *iBiasH2 * axisBias;
01238 const FLOAT Sbias = *iBiasS * axisBias;
01239 const FLOAT Vbias = *iBiasV * axisBias;
01240
01241 ushort start,stop;
01242
01243 if(axis == 'z')
01244 {
01245 start = 0;
01246 stop = Zstop;
01247 }
01248 else
01249 {
01250 start = *itsStartItr;
01251 stop = *itsStopItr;
01252 }
01253
01254
01255 frameBufferItr = frameBufferBegin;
01256
01257 int posMod = 0;
01258 if(axis == 'y')
01259 posMod = pos%itsImageSizeX;
01260 else if(axis == 'x')
01261 posMod = pos/itsImageSizeX;
01262
01263 typename std::vector<FLOAT>::const_iterator k = kalmanKernelbegin +
01264 (*itsKStartItr);
01265
01266
01267 for(ushort i = start; i < stop; i++, ++k)
01268 {
01269
01270 PIXTYPE curr;
01271 if(axis == 'z')
01272 {
01273 curr = frameBufferItr->getVal(pos);
01274 frameBufferItr++;
01275 }
01276 else if(axis == 'y')
01277 curr = itsInterImage[0].getVal(posMod,i);
01278 else
01279 curr = itsInterImage[1].getVal(i,posMod);
01280
01281
01282
01283
01284 if(curr.p[3] > SC_NEAR_BLACK)
01285 {
01286 const FLOAT H1 = (*k) * H1bias * curr.p[2];
01287 outImageItr->p[0] += curr.p[0] * H1;
01288 npixH1 += H1;
01289
01290 const FLOAT H2 = (*k) * H2bias * curr.p[2];
01291 outImageItr->p[1] += curr.p[1] * H2;
01292 npixH2 += H2;
01293 }
01294
01295
01296
01297 const FLOAT S = (*k) * Sbias;
01298 outImageItr->p[2] += curr.p[2] * S;
01299 npixS += S;
01300
01301 const FLOAT V = (*k) * Vbias;
01302 outImageItr->p[3] += curr.p[3] * V;
01303 npixV += V;
01304 }
01305
01306
01307
01308
01309 if(axis == 'x')
01310 {
01311
01312
01313 outImageItr->p[0] += inImageTrueItr->p[0] * itsOriginalImageWeight;
01314 outImageItr->p[1] += inImageTrueItr->p[1] * itsOriginalImageWeight;
01315 outImageItr->p[2] += inImageTrueItr->p[2] * itsOriginalImageWeight;
01316 outImageItr->p[3] += inImageTrueItr->p[3] * itsOriginalImageWeight;
01317
01318 npixH1 += itsOriginalImageWeight;
01319 npixH2 += itsOriginalImageWeight;
01320 npixS += itsOriginalImageWeight;
01321 npixV += itsOriginalImageWeight;
01322 }
01323 if(npixH1 != 0)
01324 outImageItr->p[0] = outImageItr->p[0]/npixH1;
01325 if(npixH2 != 0)
01326 outImageItr->p[1] = outImageItr->p[1]/npixH2;
01327 if(npixS != 0)
01328 outImageItr->p[2] = outImageItr->p[2]/npixS;
01329 if(npixV != 0)
01330 outImageItr->p[3] = outImageItr->p[3]/npixV;
01331 }
01332
01333
01334 if(axis == 'x')
01335 {
01336 if(outImageItr->p[0] < 0)
01337 outImageItr->p[0] = 0;
01338 if(outImageItr->p[1] < 0)
01339 outImageItr->p[1] = 0;
01340 if(outImageItr->p[2] < 0)
01341 outImageItr->p[2] = 0;
01342 if(outImageItr->p[3] < 0)
01343 outImageItr->p[3] = 0;
01344 }
01345 }
01346
01347
01348
01349
01350 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
01351 Image<PixRGB<FLOAT> > SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCgetSharpened(
01352 const PIXTYPE scale_factor)
01353 const
01354 {
01355 if(itsOutputReady)
01356 {
01357 const Image<PIXTYPE> fbuffer = *itsFrameCurrent;
01358
01359
01360 const Image<PIXTYPE> diffimg = fbuffer - itsOutImage;
01361
01362
01363 Image<PIXTYPE> finalimg;
01364 finalimg.resize(fbuffer.getWidth(), fbuffer.getHeight());
01365
01366
01367
01368 typename Image<PIXTYPE>::const_iterator dimg = diffimg.begin();
01369 typename Image<PIXTYPE>::const_iterator fimg = fbuffer.begin();
01370
01371 typename Image<FLOAT>::const_iterator iBiasH1 = itsLocalBiasH1.begin();
01372 typename Image<FLOAT>::const_iterator iBiasH2 = itsLocalBiasH2.begin();
01373 typename Image<FLOAT>::const_iterator iBiasS = itsLocalBiasS.begin();
01374 typename Image<FLOAT>::const_iterator iBiasV = itsLocalBiasV.begin();
01375
01376 for(typename Image<PIXTYPE>::iterator aptr = finalimg.beginw();
01377 aptr != finalimg.endw();
01378 ++aptr, ++dimg, ++fimg , ++iBiasH1, ++iBiasH2, ++iBiasS, ++iBiasV)
01379 {
01380 aptr->p[0] = ((dimg->p[0] * scale_factor.p[0] * *iBiasH1) + fimg->p[0]);
01381 if(aptr->p[0] > 1) aptr->p[0] = 1;
01382 aptr->p[1] = ((dimg->p[1] * scale_factor.p[1] * *iBiasH2) + fimg->p[1]);
01383 if(aptr->p[1] > 1) aptr->p[1] = 1;
01384 aptr->p[2] = ((dimg->p[2] * scale_factor.p[2] * *iBiasS) + fimg->p[2]);
01385 if(aptr->p[2] > 1) aptr->p[2] = 1;
01386 aptr->p[3] = ((dimg->p[3] * scale_factor.p[3] * *iBiasV) + fimg->p[3]);
01387 if(aptr->p[3] > 1) aptr->p[3] = 1;
01388 }
01389
01390 return static_cast<Image<PixRGB<FLOAT> > >(finalimg);
01391 }
01392 else
01393 {
01394 Image<PixRGB<FLOAT> > blank; blank.resize(itsImageSizeX,itsImageSizeY);
01395 typename Image<PixRGB<FLOAT> >::iterator ib = blank.beginw();
01396
01397 PixRGB<FLOAT>bp = PixRGB<FLOAT>(0,0,0);
01398
01399 while(ib != blank.endw()) {*ib = bp; ++ib;}
01400
01401 return blank;
01402 }
01403 }
01404
01405
01406
01407 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
01408 Image<PixRGB<FLOAT> > SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCgetFrame()
01409 const
01410 {
01411 if(itsOutputReady)
01412 {
01413 return itsFinalImage;
01414 }
01415 else
01416 {
01417 Image<PixRGB<FLOAT> > blank; blank.resize(itsImageSizeX,itsImageSizeY);
01418 typename Image<PixRGB<FLOAT> >::iterator ib = blank.beginw();
01419
01420 PixRGB<FLOAT>bp = PixRGB<FLOAT>(0,0,0);
01421
01422 while(ib != blank.endw()) {*ib = bp; ++ib;}
01423
01424 return blank;
01425 }
01426 }
01427
01428
01429
01430 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
01431 Image<PixRGB<FLOAT> > SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCgetOutImage()
01432 const
01433 {
01434 Image<PixRGB<FLOAT> > returnImage;
01435 returnImage.resize(itsOutImage.getWidth(),itsOutImage.getHeight());
01436 typename Image<PixRGB<FLOAT> >::iterator returnImageItr =
01437 returnImage.beginw();
01438 typename Image<PIXTYPE>::const_iterator outImageItr =
01439 itsOutImage.begin();
01440 while(returnImageItr != returnImage.endw())
01441 {
01442 *returnImageItr = PixRGB<FLOAT>(*outImageItr);
01443 ++returnImageItr; ++outImageItr;
01444 }
01445
01446 return returnImage;
01447 }
01448
01449
01450
01451 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
01452 Image<PixRGB<FLOAT> > SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCgetInImage()
01453 const
01454 {
01455 if(itsOutputReady)
01456 {
01457 Image<PixRGB<FLOAT> > returnImage;
01458 const Image<PIXTYPE> fbuffer = *itsFrameCurrent;
01459 returnImage.resize(itsFrameCurrent->getWidth(),
01460 itsFrameCurrent->getHeight());
01461 typename Image<PixRGB<FLOAT> >::iterator returnImageItr =
01462 returnImage.beginw();
01463 typename Image<PIXTYPE>::const_iterator inImageItr = fbuffer.begin();
01464
01465 while(returnImageItr != returnImage.endw())
01466 {
01467 *returnImageItr = PixRGB<FLOAT>(*inImageItr);
01468 ++returnImageItr; ++inImageItr;
01469 }
01470 return returnImage;
01471 }
01472 else
01473 {
01474 Image<PixRGB<FLOAT> > blank; blank.resize(itsImageSizeX,itsImageSizeY);
01475 typename Image<PixRGB<FLOAT> >::iterator ib = blank.beginw();
01476
01477 PixRGB<FLOAT>bp = PixRGB<FLOAT>(0,0,0);
01478
01479 while(ib != blank.endw()) {*ib = bp; ++ib;}
01480
01481 return blank;
01482 }
01483 }
01484
01485
01486 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
01487 Image<PIXTYPE> SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCgetRawOutImage() const
01488 {
01489 return itsOutImage;
01490 }
01491
01492
01493
01494 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
01495 Image<PIXTYPE> SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCgetRawInImage() const
01496 {
01497 if(itsOutputReady)
01498 {
01499 return *itsFrameCurrent;
01500 }
01501 else
01502 {
01503 Image<PIXTYPE> blank; blank.resize(itsImageSizeX,itsImageSizeY);
01504 typename Image<PIXTYPE>::iterator ib = blank.beginw();
01505
01506 PIXTYPE bp = PIXTYPE(0,0,0,0);
01507 while(ib != blank.endw()) {*ib = bp; ++ib;}
01508
01509 return blank;
01510 }
01511 }
01512
01513
01514
01515 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
01516 Image<BETATYPE> SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCgetBetaImage() const
01517 {
01518 if(itsOutputReady)
01519 {
01520 return *itsBetaCurrent;
01521 }
01522 else
01523 {
01524 Image<BETATYPE> blank; blank.resize(itsImageSizeX,itsImageSizeY);
01525 typename Image<BETATYPE>::iterator ib = blank.beginw();
01526
01527 PixHyper<FLOAT,SC_MAX_CHANNELS> bp = PixHyper<FLOAT,SC_MAX_CHANNELS>(0);
01528
01529 while(ib != blank.endw()) {*ib = bp; ++ib;}
01530
01531 return blank;
01532 }
01533 }
01534
01535
01536
01537 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
01538 ushort SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCgetTemporalOffset() const
01539 {
01540 return itsTemporalOffset;
01541 }
01542
01543
01544
01545 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
01546 bool SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCisOutputReady() const
01547 {
01548 return itsOutputReady;
01549 }
01550
01551
01552
01553 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
01554 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCgetLocalBiasImages(
01555 Image<FLOAT> &H1, Image<FLOAT> &H2,
01556 Image<FLOAT> &S, Image<FLOAT> &V) const
01557 {
01558 if(itsOutputReady)
01559 {
01560 H1 = itsLocalBiasH1; H2 = itsLocalBiasH2;
01561 S = itsLocalBiasS; V = itsLocalBiasV;
01562 }
01563 else
01564 {
01565 Image<FLOAT> blank; blank.resize(itsImageSizeX,itsImageSizeY);
01566 typename Image<FLOAT>::iterator ib = blank.beginw();
01567 FLOAT bp = 0;
01568
01569 while(ib != blank.endw()) {*ib = bp; ++ib;}
01570
01571 H1 = blank; H2 = blank; S = blank; V = blank;
01572 }
01573 }
01574
01575
01576
01577 template <class PIXTYPE, class BETATYPE, class FLOAT> inline
01578 void SurpriseControl<PIXTYPE,BETATYPE,FLOAT>::SCgetSeperableParts(
01579 Image<PIXTYPE> &Zimg,
01580 Image<PIXTYPE> &Yimg) const
01581 {
01582 if(itsOutputReady)
01583 {
01584 Zimg = itsInterImage[0];
01585 Yimg = itsInterImage[1];
01586 }
01587 else
01588 {
01589 Image<PIXTYPE> blank; blank.resize(itsImageSizeX,itsImageSizeY);
01590 typename Image<PIXTYPE>::iterator ib = blank.beginw();
01591
01592 PIXTYPE bp = PIXTYPE(0,0,0,0);
01593 while(ib != blank.endw()) {*ib = bp; ++ib;}
01594
01595 Zimg = blank; Yimg = blank;
01596 }
01597 }
01598
01599
01600
01601 template class SurpriseControl<PixH2SV1<float>,
01602 PixHyper<float,SC_MAX_CHANNELS>,float>;
01603 template class SurpriseControl<PixH2SV2<float>,
01604 PixHyper<float,SC_MAX_CHANNELS>,float>;
01605
01606 #endif