00001 /*!@file AppMedia/stim-surprise.C generate surprising stimuli */ 00002 00003 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/AppMedia/stim-foe-background.C $ 00004 // $Id: stim-foe-background.C 12962 2010-03-06 02:13:53Z irock $ 00005 00006 #include "Image/Image.H" 00007 #include "Image/DrawOps.H" 00008 #include "Image/ShapeOps.H" 00009 #include "Util/MathFunctions.H" 00010 #include "Image/Pixels.H" 00011 #include "Raster/Raster.H" 00012 00013 #include <vector> 00014 00015 #define WIDTH 1280 00016 #define HEIGHT 720 00017 #define NFRAME 500 00018 #define DX 72 00019 #define DX_DOT_OVERLAP 3 00020 #define DTHETA 0.1 00021 #define RAD 8 00022 00023 #define DOT_RAD 5 00024 #define DOT_SPEED_PIXEL_PER_FRAME 2 00025 00026 #define DOT_DEATH_RATE_PERCENT 0 00027 00028 #define DOT_LIFE_TIME 1000 00029 #define RATIO 100 00030 00031 00032 template <class T> 00033 void drawDisk2(Image<T>& dst, const Point2D<int>& center, 00034 const float radius, const T value) 00035 { 00036 if (radius == 1) 00037 { 00038 if (dst.coordsOk(center)) dst.setVal(center.i + dst.getWidth() * center.j, value); 00039 return; 00040 } 00041 00042 for (int y = -int(radius); y <= int(radius); ++y) 00043 { 00044 int bound = int(sqrtf(float(squareOf(radius) - squareOf(y)))); 00045 for (int x = -bound; x <= bound; ++x) 00046 if (dst.coordsOk(x + center.i, y + center.j)) 00047 dst.setVal(x + center.i, y + center.j, value); 00048 } 00049 } 00050 00051 00052 int main(const int argc, const char **argv) 00053 { 00054 initRandomNumbers(); 00055 Image<PixRGB<byte> > img(WIDTH, HEIGHT, NO_INIT); 00056 00057 if (argc < 2) LFATAL("USAGE: stim_surprise <type>"); 00058 00059 00060 // arrays of precessing dots and one is special in there? 00061 00062 if (strcmp(argv[1], "foe") == 0 || strcmp(argv[1], "foc") == 0) 00063 { 00064 00065 img.clear(PixRGB<byte>(128,128,128)); 00066 //Raster::WriteRGB(img, "greyframe.ppm"); 00067 int direction=0; 00068 if (strcmp(argv[1], "foe") == 0){ 00069 direction=1; 00070 } 00071 if (strcmp(argv[1], "foc") == 0){ 00072 direction=-1; 00073 } 00074 Point2D<float> foe= Point2D<float>(float(float(WIDTH)*9/10) , float(float(HEIGHT)*9/10)); 00075 // get random centers: 00076 std::vector<Point2D<float> > center; 00077 std::vector<int > center_life; 00078 std::vector<float> center_depth; 00079 00080 std::vector<Point2D<float> > temp; 00081 std::vector<int > temp_life; 00082 std::vector<float> temp_depth; 00083 //initialize 00084 std::vector<double> phi; 00085 for (int j = DX/2; j < HEIGHT; j += DX) 00086 for (int i = DX/2; i < WIDTH; i += DX) 00087 { 00088 center.push_back(Point2D<float>(i + float(10.0 * (randomDouble()-5.0)), j + float(10.0 * (randomDouble()-5.0)))); 00089 center_life.push_back(4); 00090 phi.push_back(M_PI * randomDouble()); 00091 } 00092 00093 int count=0; 00094 unsigned int count_dots_disregard=0; 00095 for (int k = 0; k < NFRAME; k ++){ 00096 PixRGB<byte> col_in_white = PixRGB<byte>(256,256,256); 00097 PixRGB<byte> col_out_black = PixRGB<byte>(0,0,0); 00098 img.clear(PixRGB<byte>(128,128,128)); 00099 count_dots_disregard=0; 00100 for (unsigned int n = 0; n < center.size(); n ++) 00101 { 00102 // check if they have gone out 00103 if(direction>0) //foe 00104 { 00105 float ii,jj; 00106 if(k==0){ 00107 ii = float(center[n].i ); 00108 jj = float(center[n].j ); 00109 }else{ 00110 ii = float(center[n].i + direction*float(center[n].i-foe.i)*float(DOT_SPEED_PIXEL_PER_FRAME)/RATIO ); 00111 jj = float(center[n].j + direction*float(center[n].j-foe.j)*float(DOT_SPEED_PIXEL_PER_FRAME)/RATIO ); 00112 if(ii==center[n].i){ 00113 if( (center[n].i-foe.i)<0 ) 00114 ii=float(ii-1); 00115 else 00116 ii=float(ii+1); 00117 } 00118 if(jj==center[n].j){ 00119 jj=float(jj+1); 00120 if( (center[n].j-foe.j)<0 ) 00121 jj=float(jj-1); 00122 else 00123 jj=float(jj+1); 00124 } 00125 } 00126 if(ii < WIDTH && ii> 0 && jj< HEIGHT && jj> 0 && center_life[n]<DOT_LIFE_TIME ){ 00127 temp.push_back(Point2D<float>(ii, jj)); 00128 temp_life.push_back(center_life[n]+1); 00129 }else{ 00130 count_dots_disregard++; 00131 } 00132 00133 } 00134 00135 if(direction<0) //foc 00136 { 00137 float ii = float(center[n].i + direction*(center[n].i-foe.i)*(k*DOT_SPEED_PIXEL_PER_FRAME)/DOT_LIFE_TIME ); 00138 if(ii > WIDTH || ii< 0){ 00139 //ii = float(center[n].i + direction*(center[n].i-foe.i)*(theta-count*DOT_SPEED_PIXEL_PER_FRAME)/DOT_LIFE_TIME ); 00140 } 00141 //center[n].i=ii; 00142 float jj = float(center[n].j + direction*(center[n].j-foe.j)*(k*DOT_SPEED_PIXEL_PER_FRAME)/DOT_LIFE_TIME ); 00143 if(jj > HEIGHT || jj< 0){ 00144 //jj = float(center[n].j + direction*(center[n].j-foe.j)*(theta-count*DOT_SPEED_PIXEL_PER_FRAME)/DOT_LIFE_TIME ); 00145 } 00146 //center[n].j=jj; 00147 00148 drawDisk(img, Point2D<int>(ii, jj), DOT_RAD*2, col_out_black); 00149 drawDisk(img, Point2D<int>(ii, jj), DOT_RAD, col_in_white); 00150 } 00151 00152 } 00153 00154 00155 for (unsigned int a = 0; a < count_dots_disregard; a ++){ 00156 float temp_i,temp_j; 00157 //bool good=false; 00158 temp_i=float(WIDTH * (randomDouble())); 00159 temp_j=float(HEIGHT * (randomDouble())); 00160 /*while(!good){ 00161 temp_i=int(WIDTH * (randomDouble())); 00162 temp_j=int(WIDTH * (randomDouble())); 00163 bool overlap=false; 00164 for (unsigned int n = 0; n < temp.size(); n ++){ 00165 if(abs(temp_i-temp[n].i)<DX_DOT_OVERLAP || abs(temp_j-temp[n].j)<DX_DOT_OVERLAP){ 00166 overlap=true; 00167 break; 00168 } 00169 } 00170 if(!overlap){ 00171 good=true; 00172 } 00173 }*/ 00174 temp.push_back(Point2D<float>(temp_i , temp_j )); 00175 temp_life.push_back(0); 00176 } 00177 00178 // Draw dots 00179 center.clear(); 00180 center_life.clear(); 00181 for (unsigned int n = 0; n < temp.size(); n ++){ 00182 center.push_back(temp[n]); 00183 center_life.push_back(temp_life[n]); 00184 if(1 ){ //float(temp_life[n]/10)< float(DOT_RAD*2) 00185 drawDisk2(img, Point2D<int>(int(temp[n].i), int(temp[n].j) ), float(float(temp_life[n])/15*2), col_out_black); 00186 drawDisk2(img, Point2D<int>(int(temp[n].i), int(temp[n].j) ), float(temp_life[n])/15, col_in_white); 00187 } 00188 else if(temp_life[n]> 99999){ //(DOT_LIFE_TIME-DOT_RAD) 00189 drawDisk2(img, Point2D<int>(int(temp[n].i), int(temp[n].j) ), (DOT_LIFE_TIME-temp_life[n])*2, col_out_black); 00190 drawDisk2(img, Point2D<int>(int(temp[n].i), int(temp[n].j) ), DOT_LIFE_TIME-temp_life[n], col_in_white); 00191 }else{ 00192 drawDisk2(img, Point2D<int>(int(temp[n].i), int(temp[n].j) ), float(DOT_RAD*2), col_out_black); 00193 drawDisk2(img, Point2D<int>(int(temp[n].i), int(temp[n].j) ), float(DOT_RAD), col_in_white); 00194 } 00195 } 00196 temp.clear(); 00197 temp_life.clear(); 00198 Raster::WriteRGB(img, sformat("/home2/tmp/u/elno/research/exp1/stim/bgMovies/foe/frames/frame%06d.ppm", k)); 00199 //theta += DOT_SPEED_PIXEL_PER_FRAME; //thetac -= DTHETA; // += 3.67 * DTHETA; 00200 count++; 00201 if(count>DOT_LIFE_TIME) 00202 count=0; 00203 } 00204 } 00205 // random noise? 00206 00207 // arrays of precessing dots and one is special in there? 00208 else if (strcmp(argv[1], "dots") == 0) 00209 { 00210 // get random centers: 00211 std::vector<Point2D<int> > center; std::vector<double> phi; 00212 for (int j = DX/2; j < WIDTH; j += DX) 00213 for (int i = DX/2; i < WIDTH; i += DX) 00214 { 00215 center.push_back(Point2D<int>(i + int(5.0 * (randomDouble()-0.5)), 00216 j + int(5.0 * (randomDouble()-0.5)))); 00217 phi.push_back(M_PI * randomDouble()); 00218 } 00219 00220 double theta = 0.0, thetac = 0.0;; 00221 for (int k = 0; k < NFRAME; k ++) 00222 { 00223 img.clear(); 00224 00225 for (unsigned int n = 0; n < center.size(); n ++) 00226 { 00227 double t = theta, rx = RAD, ry = RAD, p = phi[n]; 00228 PixRGB<byte> col= PixRGB<byte>(256,256,256); 00229 if (n == 27) t = thetac; 00230 //if (n == 27) { rx = 0; ry = 0; if ((k/6) & 1) col = 0; } 00231 00232 int ii = int(center[n].i + rx * cos(t + p)); 00233 int jj = int(center[n].j + ry * sin(t + p)); 00234 drawDisk(img, Point2D<int>(ii, jj), 4, col); 00235 } 00236 00237 Raster::WriteRGB(img, sformat("frame%06d.ppm", k)); 00238 theta += DTHETA; //thetac -= DTHETA; // += 3.67 * DTHETA; 00239 } 00240 } 00241 // random noise? 00242 else if (strcmp(argv[1], "rnd") == 0) 00243 { 00244 for (int k = 0; k < NFRAME; k ++) 00245 { 00246 for (int j = 0; j < WIDTH; j ++) 00247 for (int i = 0; i < WIDTH; i ++) 00248 { 00249 00250 double d2 = (i-127)*(i-127) + (j-127)*(j-127); 00251 double coeff = exp(-d2 / 400.0) * 0.5; 00252 00253 img.setVal(i, j, 128 + int(256.0 * (1.0-coeff) * randomDouble()) - 00254 int(128.0 * (1.0-coeff))); 00255 } 00256 Raster::WriteRGB(img, sformat("frame%06d.ppm", k)); 00257 } 00258 } 00259 // random blinking? 00260 else if (strcmp(argv[1], "blink") == 0) 00261 { 00262 // get random centers: 00263 std::vector<Point2D<int> > center; std::vector<int> phi; 00264 const int period = 20; 00265 for (int j = DX/2; j < WIDTH; j += DX) 00266 for (int i = DX/2; i < WIDTH; i += DX) 00267 { 00268 center.push_back(Point2D<int>(i + int(5.0 * (randomDouble()-0.5)), 00269 j + int(5.0 * (randomDouble()-0.5)))); 00270 phi.push_back(randomUpToNotIncluding(period)); 00271 } 00272 00273 for (int k = 0; k < NFRAME; k ++) 00274 { 00275 img.clear(); 00276 00277 for (unsigned int n = 0; n < center.size(); n ++) 00278 { 00279 PixRGB<byte> col= PixRGB<byte>(256,256,256); 00280 if (n == 27) 00281 { 00282 if (((k + phi[n]) & 4) < 2) col = PixRGB<byte>(256,256,256); else col = PixRGB<byte>(0,0,0); 00283 } 00284 else 00285 { 00286 if (((k + phi[n]) % period) < period/2) col = PixRGB<byte>(256,256,256); 00287 else col = PixRGB<byte>(0,0,0); 00288 } 00289 drawDisk(img, center[n], 4, col); 00290 } 00291 00292 Raster::WriteRGB(img, sformat("frame%06d.ppm", k)); 00293 00294 } 00295 } 00296 return 0; 00297 } 00298 00299 // ###################################################################### 00300 /* So things look consistent in everyone's emacs... */ 00301 /* Local Variables: */ 00302 /* indent-tabs-mode: nil */ 00303 /* End: */