00001 /*!@file Psycho/StimAnalyzer.C make different kind of visual test stimuli 00002 */ 00003 00004 // //////////////////////////////////////////////////////////////////// // 00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00006 // University of Southern California (USC) and the iLab at USC. // 00007 // See http://iLab.usc.edu for information about this project. // 00008 // //////////////////////////////////////////////////////////////////// // 00009 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00010 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00011 // in Visual Environments, and Applications'' by Christof Koch and // 00012 // Laurent Itti, California Institute of Technology, 2001 (patent // 00013 // pending; application number 09/912,225 filed July 23, 2001; see // 00014 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00015 // //////////////////////////////////////////////////////////////////// // 00016 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00017 // // 00018 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00019 // redistribute it and/or modify it under the terms of the GNU General // 00020 // Public License as published by the Free Software Foundation; either // 00021 // version 2 of the License, or (at your option) any later version. // 00022 // // 00023 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00024 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00025 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00026 // PURPOSE. See the GNU General Public License for more details. // 00027 // // 00028 // You should have received a copy of the GNU General Public License // 00029 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00030 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00031 // Boston, MA 02111-1307 USA. // 00032 // //////////////////////////////////////////////////////////////////// // 00033 // 00034 // Primary maintainer for this file: T. Nathan Mundhenk <mundhenk@usc.edu> 00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Psycho/StimAnalyzer.C $ 00036 // $Id: StimAnalyzer.C 6795 2006-06-29 20:45:32Z rjpeters $ 00037 00038 00039 #ifndef STIM_ANALYZER_C_DEFINED 00040 #define STIM_ANALYZER_C_DEFINED 00041 00042 #include "Psycho/StimAnalyzer.H" 00043 #include <cfloat> 00044 #include <fstream> 00045 #include <iostream> 00046 00047 using namespace std; 00048 00049 StimAnalyzer::StimAnalyzer(const int frames, const ushort conditions) 00050 { 00051 itsGTtargetColor.set(255.0F,255.0F,255.0F); 00052 itsGTtargetColorPatch1.set(0.0F,128.0F,128.0F); 00053 itsGTtargetColorPatch2.set(0.0F,0.0F,255.0F); 00054 itsGTtargetColorPatch1off.set(128.0F,128.0F,0.0F); 00055 itsGTtargetColorPatch2off.set(255.0F,0.0F,0.0F); 00056 itsGTdistColor.set(128.0F,128.0F,128.0F); 00057 SAinit(frames,conditions); 00058 } 00059 00060 /*****************************************************************************/ 00061 00062 StimAnalyzer::~StimAnalyzer() 00063 {} 00064 00065 /*****************************************************************************/ 00066 00067 void StimAnalyzer::SAinit(const int frames, const ushort conditions) 00068 { 00069 itsFrames = frames; 00070 itsConditions = conditions; 00071 00072 itsTargetFrameOn.resize(frames,false); 00073 itsDistFrameOn.resize(frames,false); 00074 itsOtherFrameOn.resize(frames,false); 00075 00076 itsTargetFrameNumber.resize(frames,0); 00077 itsDistFrameNumber.resize(frames,0); 00078 itsOtherFrameNumber.resize(frames,0); 00079 00080 itsTargetFrameTotalONNumber.resize(itsConditions,0); 00081 itsDistFrameTotalONNumber.resize(itsConditions,0); 00082 itsOtherFrameTotalONNumber.resize(itsConditions,0); 00083 00084 itsTargetFrameSum.resize(frames,0.0F); 00085 itsDistFrameSum.resize(frames,0.0F); 00086 itsOtherFrameSum.resize(frames,0.0F); 00087 00088 itsTargetFrameSS.resize(frames,0.0F); 00089 itsDistFrameSS.resize(frames,0.0F); 00090 itsOtherFrameSS.resize(frames,0.0F); 00091 00092 itsTargetFrameMin.resize(frames,DBL_MAX); 00093 itsDistFrameMin.resize(frames,DBL_MAX); 00094 itsOtherFrameMin.resize(frames,DBL_MAX); 00095 00096 itsTargetFrameMax.resize(frames,0.0F); 00097 itsDistFrameMax.resize(frames,0.0F); 00098 itsOtherFrameMax.resize(frames,0.0F); 00099 00100 itsTargetFrameMean.resize(frames,0.0F); 00101 itsDistFrameMean.resize(frames,0.0F); 00102 itsOtherFrameMean.resize(frames,0.0F); 00103 00104 itsTargetFrameStd.resize(frames,0.0F); 00105 itsDistFrameStd.resize(frames,0.0F); 00106 itsOtherFrameStd.resize(frames,0.0F); 00107 00108 itsTargetFrameTotalONSum.resize(itsConditions,0.0F); 00109 itsDistFrameTotalONSum.resize(itsConditions,0.0F); 00110 itsOtherFrameTotalONSum.resize(itsConditions,0.0F); 00111 00112 itsTargetFrameTotalONSS.resize(itsConditions,0.0F); 00113 itsDistFrameTotalONSS.resize(itsConditions,0.0F); 00114 itsOtherFrameTotalONSS.resize(itsConditions,0.0F); 00115 00116 itsTargetFrameTotalONMin.resize(itsConditions,DBL_MAX); 00117 itsDistFrameTotalONMin.resize(itsConditions,DBL_MAX); 00118 itsOtherFrameTotalONMin.resize(itsConditions,DBL_MAX); 00119 00120 itsTargetFrameTotalONMax.resize(itsConditions,0.0F); 00121 itsDistFrameTotalONMax.resize(itsConditions,0.0F); 00122 itsOtherFrameTotalONMax.resize(itsConditions,0.0F); 00123 00124 itsTargetFrameTotalONMean.resize(itsConditions,0.0F); 00125 itsDistFrameTotalONMean.resize(itsConditions,0.0F); 00126 itsOtherFrameTotalONMean.resize(itsConditions,0.0F); 00127 00128 itsTargetFrameTotalONStd.resize(itsConditions,0.0F); 00129 itsDistFrameTotalONStd.resize(itsConditions,0.0F); 00130 itsOtherFrameTotalONStd.resize(itsConditions,0.0F); 00131 } 00132 00133 /*****************************************************************************/ 00134 00135 void StimAnalyzer::SAinputImages(const Image<double> salmap, 00136 const Image<PixRGB<double> > groundTruth, 00137 const uint frame, 00138 const ushort condition) 00139 { 00140 itsSalMap = salmap; 00141 itsGroundTruth = groundTruth; 00142 itsFrame = frame; 00143 itsCondition = condition; 00144 SAcompImages(); 00145 } 00146 00147 /*****************************************************************************/ 00148 00149 void StimAnalyzer::SAcompImages() 00150 { 00151 double targetMax = 0.0F; double targetMin = DBL_MAX; 00152 double distMax = 0.0F; double distMin = DBL_MAX; 00153 double otherMax = 0.0F; double otherMin = DBL_MAX; 00154 00155 int targetN = 0; double sumTarget = 0.0F; double ssTarget = 0.0F; 00156 int distN = 0; double sumDist = 0.0F; double ssDist = 0.0F; 00157 int otherN = 0; double sumOther = 0.0F; double ssOther = 0.0F; 00158 00159 Image<double>::iterator salMapItr = itsSalMap.beginw(); 00160 Image<PixRGB<double> >::iterator groundTruthItr = itsGroundTruth.beginw(); 00161 00162 // Get the saliency values over Targets, distractors and other pixels 00163 00164 while(salMapItr != itsSalMap.endw()) 00165 { 00166 if((*groundTruthItr == itsGTtargetColor))// || 00167 /// (*groundTruthItr == itsGTtargetColorPatch1) || 00168 // (*groundTruthItr == itsGTtargetColorPatch2)) 00169 { 00170 if(*salMapItr > targetMax) 00171 targetMax = *salMapItr; 00172 else if(*salMapItr < targetMin) 00173 targetMin = *salMapItr; 00174 00175 sumTarget += *salMapItr; 00176 ssTarget += pow(*salMapItr,2.0); 00177 targetN++; 00178 } 00179 else if(*groundTruthItr == itsGTdistColor) 00180 { 00181 if(*salMapItr > distMax) 00182 distMax = *salMapItr; 00183 else if(*salMapItr < distMin) 00184 distMin = *salMapItr; 00185 00186 sumDist += *salMapItr; 00187 ssDist += pow(*salMapItr,2.0); 00188 distN++; 00189 } 00190 else 00191 { 00192 if(*salMapItr > otherMax) 00193 otherMax = *salMapItr; 00194 else if(*salMapItr < otherMin) 00195 otherMin = *salMapItr; 00196 00197 sumOther += *salMapItr; 00198 ssOther += pow(*salMapItr,2.0); 00199 otherN++; 00200 } 00201 ++salMapItr; ++groundTruthItr; 00202 } 00203 00204 // Set whether targets and distractors are On or Off in this frame 00205 00206 if(targetN != 0) 00207 itsTargetFrameOn[itsFrame] = true; 00208 if(distN != 0) 00209 itsDistFrameOn[itsFrame] = true; 00210 if(otherN != 0) 00211 itsOtherFrameOn[itsFrame] = true; 00212 00213 // set the final stat values for this frame 00214 00215 itsTargetFrameNumber[itsFrame] = targetN; 00216 itsDistFrameNumber[itsFrame] = distN; 00217 itsOtherFrameNumber[itsFrame] = otherN; 00218 00219 itsTargetFrameSum[itsFrame] = sumTarget; 00220 itsDistFrameSum[itsFrame] = sumDist; 00221 itsOtherFrameSum[itsFrame] = sumOther; 00222 00223 itsTargetFrameSS[itsFrame] = ssTarget; 00224 itsDistFrameSS[itsFrame] = ssDist; 00225 itsOtherFrameSS[itsFrame] = ssOther; 00226 00227 itsTargetFrameMin[itsFrame] = targetMin; 00228 itsDistFrameMin[itsFrame] = distMin; 00229 itsOtherFrameMin[itsFrame] = otherMin; 00230 00231 itsTargetFrameMax[itsFrame] = targetMax; 00232 itsDistFrameMax[itsFrame] = distMax; 00233 itsOtherFrameMax[itsFrame] = otherMax; 00234 00235 // compute mean and std for this frame 00236 00237 itsTargetFrameMean[itsFrame] = sumTarget/targetN; 00238 itsDistFrameMean[itsFrame] = sumDist/distN; 00239 itsOtherFrameMean[itsFrame] = sumOther/otherN; 00240 00241 itsTargetFrameStd[itsFrame] = sqrt((ssTarget/targetN) 00242 - pow(itsTargetFrameMean[itsFrame],2.0)); 00243 itsDistFrameStd[itsFrame] = sqrt((ssDist/distN) 00244 - pow(itsDistFrameMean[itsFrame],2.0)); 00245 itsOtherFrameStd[itsFrame] = sqrt((ssOther/otherN) 00246 - pow(itsOtherFrameMean[itsFrame],2.0)); 00247 00248 // gather values for this "condition" 00249 // additionally, keep track of whether the item is On or Off 00250 // in this frame 00251 00252 if(itsTargetFrameOn[itsFrame]) 00253 { 00254 itsTargetFrameTotalONNumber[itsCondition] += targetN; 00255 itsTargetFrameTotalONSum[itsCondition] += sumTarget; 00256 itsTargetFrameTotalONSS[itsCondition] += pow(sumTarget,2.0); 00257 if(targetMin < itsTargetFrameTotalONMin[itsCondition]) 00258 itsTargetFrameTotalONMin[itsCondition] = targetMin; 00259 else if (targetMax > itsTargetFrameTotalONMax[itsCondition]) 00260 itsTargetFrameTotalONMax[itsCondition] = targetMax; 00261 } 00262 00263 if(itsDistFrameOn[itsFrame]) 00264 { 00265 itsDistFrameTotalONNumber[itsCondition] += distN; 00266 itsDistFrameTotalONSum[itsCondition] += sumDist; 00267 itsDistFrameTotalONSS[itsCondition] += pow(sumDist,2.0); 00268 if(distMin < itsDistFrameTotalONMin[itsCondition]) 00269 itsDistFrameTotalONMin[itsCondition] = distMin; 00270 else if (distMax > itsDistFrameTotalONMax[itsCondition]) 00271 itsDistFrameTotalONMax[itsCondition] = distMax; 00272 } 00273 00274 if(itsOtherFrameOn[itsFrame]) 00275 { 00276 itsOtherFrameTotalONNumber[itsCondition] += otherN; 00277 itsOtherFrameTotalONSum[itsCondition] += sumOther; 00278 itsOtherFrameTotalONSS[itsCondition] += pow(sumOther,2.0); 00279 if(otherMin < itsOtherFrameTotalONMin[itsCondition]) 00280 itsOtherFrameTotalONMin[itsCondition] = otherMin; 00281 else if (otherMax > itsOtherFrameTotalONMax[itsCondition]) 00282 itsOtherFrameTotalONMax[itsCondition] = otherMax; 00283 } 00284 } 00285 00286 /*****************************************************************************/ 00287 00288 void StimAnalyzer::SAfinalStats() 00289 { 00290 00291 for(ushort i = 0; i < itsConditions; i++) 00292 { 00293 // compute means over conditions 00294 itsTargetFrameTotalONMean[i] = 00295 itsTargetFrameTotalONSum[i]/itsTargetFrameTotalONNumber[i]; 00296 itsDistFrameTotalONMean[i] = 00297 itsDistFrameTotalONSum[i]/itsDistFrameTotalONNumber[i]; 00298 itsOtherFrameTotalONMean[i] = 00299 itsOtherFrameTotalONSum[i]/itsOtherFrameTotalONNumber[i]; 00300 00301 // computer std over conditions 00302 itsTargetFrameTotalONStd[i] = 00303 sqrt((itsTargetFrameTotalONSS[i]/itsTargetFrameTotalONNumber[i]) - 00304 pow(itsTargetFrameTotalONMean[i],2.0)); 00305 itsDistFrameTotalONStd[i] = 00306 sqrt((itsDistFrameTotalONSS[i]/itsDistFrameTotalONNumber[i]) - 00307 pow(itsDistFrameTotalONMean[i],2.0)); 00308 itsOtherFrameTotalONStd[i] = 00309 sqrt((itsOtherFrameTotalONSS[i]/itsOtherFrameTotalONNumber[i]) - 00310 pow(itsOtherFrameTotalONMean[i],2.0)); 00311 } 00312 } 00313 00314 /*****************************************************************************/ 00315 00316 void StimAnalyzer::SAdumpFrameStats(string fileName, string sample, 00317 bool printHeader) 00318 { 00319 00320 00321 if(printHeader) 00322 { 00323 ofstream out(fileName.c_str(),ios::out); 00324 00325 out << "Sample\tFrame\t"; 00326 00327 out << "Target_On\tTarget_N\tTarget_Sum\tTarget_SS\tTarget_Min\t" 00328 << "Target_Max\tTarget_Mean\tTarget_Std\t"; 00329 00330 out << "Dist_On\tDist_N\tDist_Sum\tDist_SS\tDist_Min\tDist_Max\t" 00331 << "Dist_Mean\tDist_Std\t"; 00332 00333 out << "Other_On\tOther_N\tOther_Sum\tOther_SS\tOther_Min\tOther_Max\t" 00334 << "Other_Mean\tOther_Std\t"; 00335 00336 out << "\n"; 00337 00338 out.close(); 00339 } 00340 00341 ofstream out(fileName.c_str(),ios::app); 00342 00343 for(uint i = 0; i < itsFrames; i++) 00344 { 00345 out << sample << "\t" << i << "\t"; 00346 00347 out << itsTargetFrameOn[i] << "\t" 00348 << itsTargetFrameNumber[i] << "\t" 00349 << itsTargetFrameSum[i] << "\t" 00350 << itsTargetFrameSS[i] << "\t" 00351 << itsTargetFrameMin[i] << "\t" 00352 << itsTargetFrameMax[i] << "\t" 00353 << itsTargetFrameMean[i] << "\t" 00354 << itsTargetFrameStd[i] << "\t"; 00355 00356 out << itsDistFrameOn[i] << "\t" 00357 << itsDistFrameNumber[i] << "\t" 00358 << itsDistFrameSum[i] << "\t" 00359 << itsDistFrameSS[i] << "\t" 00360 << itsDistFrameMin[i] << "\t" 00361 << itsDistFrameMax[i] << "\t" 00362 << itsDistFrameMean[i] << "\t" 00363 << itsDistFrameStd[i] << "\t"; 00364 00365 out << itsOtherFrameOn[i] << "\t" 00366 << itsOtherFrameNumber[i] << "\t" 00367 << itsOtherFrameSum[i] << "\t" 00368 << itsOtherFrameSS[i] << "\t" 00369 << itsOtherFrameMin[i] << "\t" 00370 << itsOtherFrameMax[i] << "\t" 00371 << itsOtherFrameMean[i] << "\t" 00372 << itsOtherFrameStd[i] << "\t"; 00373 00374 out << "\n"; 00375 } 00376 out.close(); 00377 } 00378 /*****************************************************************************/ 00379 00380 void StimAnalyzer::SAdumpConditionStats(string fileName, string sample, 00381 bool printHeader) 00382 { 00383 00384 00385 if(printHeader) 00386 { 00387 ofstream out(fileName.c_str(),ios::out); 00388 00389 out << "Sample\tCondition\t"; 00390 00391 out << "Target_N\tTarget_Sum\tTarget_SS\tTarget_Min\tTarget_Max\t" 00392 << "Target_Mean\tTarget_Std\t"; 00393 00394 out << "Dist_N\tDist_Sum\tDist_SS\tDist_Min\tDist_Max\t" 00395 << "Dist_Mean\tDist_Std\t"; 00396 00397 out << "Other_N\tOther_Sum\tOther_SS\tOther_Min\tOther_Max\t" 00398 << "Other_Mean\tOther_Std\t"; 00399 00400 out << "\n"; 00401 00402 out.close(); 00403 } 00404 00405 ofstream out(fileName.c_str(),ios::app); 00406 00407 for(ushort i = 0; i < itsConditions; i++) 00408 { 00409 out << sample << "\t" << i << "\t"; 00410 00411 out << itsTargetFrameTotalONNumber[i] << "\t" 00412 << itsTargetFrameTotalONSum[i] << "\t" 00413 << itsTargetFrameTotalONSS[i] << "\t" 00414 << itsTargetFrameTotalONMin[i] << "\t" 00415 << itsTargetFrameTotalONMax[i] << "\t" 00416 << itsTargetFrameTotalONMean[i] << "\t" 00417 << itsTargetFrameTotalONStd[i] << "\t"; 00418 00419 out << itsDistFrameTotalONNumber[i] << "\t" 00420 << itsDistFrameTotalONSum[i] << "\t" 00421 << itsDistFrameTotalONSS[i] << "\t" 00422 << itsDistFrameTotalONMin[i] << "\t" 00423 << itsDistFrameTotalONMax[i] << "\t" 00424 << itsDistFrameTotalONMean[i] << "\t" 00425 << itsDistFrameTotalONStd[i] << "\t"; 00426 00427 out << itsOtherFrameTotalONNumber[i] << "\t" 00428 << itsOtherFrameTotalONSum[i] << "\t" 00429 << itsOtherFrameTotalONSS[i] << "\t" 00430 << itsOtherFrameTotalONMin[i] << "\t" 00431 << itsOtherFrameTotalONMax[i] << "\t" 00432 << itsOtherFrameTotalONMean[i] << "\t" 00433 << itsOtherFrameTotalONStd[i] << "\t"; 00434 00435 out << "\n"; 00436 } 00437 out.close(); 00438 } 00439 00440 00441 00442 00443 #endif // STIM_ANALYZER_C_DEFINED