00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "Component/ModelManager.H"
00012 #include "Media/FrameSeries.H"
00013 #include "Transport/FrameIstream.H"
00014 #include "Media/MediaOpts.H"
00015 #include "Image/Image.H"
00016 #include "Image/Pixels.H"
00017 #include "Raster/Raster.H"
00018 #include "GUI/XWinManaged.H"
00019 #include "Image/ImageSet.H"
00020 #include "Image/DrawOps.H"
00021 #include "Image/ShapeOps.H"
00022 #include "Image/Kernels.H"
00023 #include "Image/Normalize.H"
00024 #include "Image/SimpleFont.H"
00025 #include "rutz/trace.h"
00026 #include <cstdio>
00027 #include <iostream>
00028 #include <string>
00029 #include <vector>
00030
00031 #define PI 3.14159265F
00032 #define THETA_LEVELS 24
00033 #define MAP_SIZE 100
00034 #define MOD_WEIGHT_WIDTH MAP_SIZE/6
00035 #define OUTPUT_RES 500
00036 #define OUT_SCALE_FACT OUTPUT_RES/MAP_SIZE
00037 #define BRIGHTNESS 10
00038
00039 using namespace std;
00040
00041 float beta(Point2D<int> i, Point2D<int> j);
00042 float M(Image<float> WeightKernel, float theta, Point2D<int> i, Point2D<int> att);
00043
00044 void initDataSet1(vector < Image<float> > &V2, Point2D<int> &attentionPoint, float &k);
00045
00046 void initDataSet2(vector< Image<float> > &V2, Point2D<int> &attentionPoint, float &k);
00047
00048 void initDataSet3(vector< Image<float> > &V2, Point2D<int> &attentionPoint, float &k);
00049
00050 void initDataSet4(vector< Image<float> > &V2, Point2D<int> &attentionPoint, float &k);
00051
00052 void initDataSet5(vector< Image<float> > &V2, Point2D<int> &attentionPoint, float &k);
00053
00054 template <class T>
00055 void drawHalfLine(Image<T>& dst,
00056 const Point2D<int>& pos, float ori, float len, const T col,
00057 const int rad = 1);
00058
00059 template <class T>
00060 void flipVertical(Image <T> &Image);
00061
00062
00063
00064 class button {
00065 public:
00066 button() {
00067 width = int(.5*OUTPUT_RES-.1*OUTPUT_RES);
00068 height = int(.5*width);
00069 rect=Rectangle(topLeft, Dims(width, height));
00070 }
00071 button(const char* t, Point2D<int> pos) {
00072 strncpy(text,t,30);
00073 width = int(.5*OUTPUT_RES-.2*OUTPUT_RES);
00074 height = width/3;
00075
00076 topLeft = pos;
00077
00078 rect=Rectangle(topLeft, Dims(width, height));
00079 }
00080
00081 bool inBounds(Point2D<int> click) {
00082 if(click.i > topLeft.i && click.i < topLeft.i+width && click.j > topLeft.j && click.j < topLeft.j+height)
00083 return true;
00084 else
00085 return false;
00086 }
00087
00088 void draw(Image<PixRGB<byte> > &img) {
00089 drawRect(img, rect, PixRGB<byte>(255,0,0));
00090 writeText(img, topLeft+height/2-8, text, PixRGB<byte>(255,255,255), PixRGB<byte>(255,0,0), SimpleFont::FIXED(8), true);
00091 }
00092
00093 char text[30];
00094 int width;
00095 int height;
00096 Point2D<int> topLeft;
00097 Rectangle rect;
00098 };
00099
00100 int main(int argc, char* argv[]) {
00101
00102
00103 ModelManager manager("Border Ownership Modulator");
00104
00105
00106 manager.start();
00107
00108
00109 rutz::shared_ptr<XWinManaged> window1;
00110
00111
00112
00113 window1.reset(new XWinManaged(Dims(int(OUTPUT_RES*1.5),OUTPUT_RES), 0, 0, "Border Ownership"));
00114
00115
00116
00117
00118 Image<float> gaussianKernel = gaussian2D<float>(MOD_WEIGHT_WIDTH);
00119 normalizeFloat(gaussianKernel, FLOAT_NORM_0_255);
00120 gaussianKernel /= 255.0F;
00121
00122
00123 Image< PixRGB<byte> > outputImage = Image< PixRGB<byte> >(Dims(OUTPUT_RES,OUTPUT_RES), ZEROS);
00124 Image< PixRGB<byte> > panelImage = Image< PixRGB<byte> >(Dims(OUTPUT_RES/2,OUTPUT_RES), ZEROS);
00125
00126
00127 vector< Image<float> > V2;
00128 V2.resize(THETA_LEVELS, Image<float>(Dims(MAP_SIZE, MAP_SIZE), ZEROS));
00129
00130 Point2D<int> attentionPoint;
00131
00132 button but_Data1("Load Data Set 1", Point2D<int>(50, 30));
00133 button but_Data2("Load Data Set 2", Point2D<int>(50, 30+1*but_Data1.height));
00134 button but_Data3("Load Data Set 3", Point2D<int>(50, 30+2*but_Data1.height));
00135 button but_Data4("Load Data Set 4", Point2D<int>(50, 30+3*but_Data1.height));
00136 button but_Data5("Load Data Set 5", Point2D<int>(50, 30+4*but_Data1.height));
00137 button but_Quit("Quit", Point2D<int>(50, OUTPUT_RES-but_Data1.height-10));
00138 but_Data1.draw(panelImage);
00139 but_Data2.draw(panelImage);
00140 but_Data3.draw(panelImage);
00141 but_Data4.draw(panelImage);
00142 but_Data5.draw(panelImage);
00143 but_Quit.draw(panelImage);
00144
00145 float neuronStrength, modulationLevel, val;
00146 float k = 3;
00147
00148 char key;
00149
00150 initDataSet1(V2, attentionPoint, k);
00151
00152 do {
00153 outputImage.clear();
00154 for(int theta_index = 0; theta_index < THETA_LEVELS; theta_index++) {
00155 for(int x = 0; x<MAP_SIZE; x++) {
00156 for(int y = 0; y<MAP_SIZE; y++) {
00157 float theta = float(theta_index)/float(THETA_LEVELS)*2.0F*PI;
00158
00159 modulationLevel = M(gaussianKernel, theta, Point2D<int>(x,y), attentionPoint);
00160 neuronStrength=V2[theta_index].getVal(x,y);
00161 val = modulationLevel * neuronStrength * k;
00162
00163
00164 if(neuronStrength > 0) {
00165 drawHalfLine(outputImage, Point2D<int>(x*OUT_SCALE_FACT, y*OUT_SCALE_FACT), -theta, OUT_SCALE_FACT*3/4, PixRGB<byte>(75,75,75));
00166 }
00167
00168
00169 if(val > 0) {
00170
00171 PixRGB<byte> curr = outputImage.getVal(x*OUT_SCALE_FACT,y*OUT_SCALE_FACT);
00172
00173
00174
00175
00176 drawHalfLine(outputImage, Point2D<int>(x*OUT_SCALE_FACT, y*OUT_SCALE_FACT), -(theta-PI/2.0f), val*10,
00177 PixRGB<byte>(curr + PixRGB<byte>(255*val*BRIGHTNESS,255*val*BRIGHTNESS, 0)) );
00178
00179 drawHalfLine(outputImage, Point2D<int>(x*OUT_SCALE_FACT, y*OUT_SCALE_FACT), theta, OUT_SCALE_FACT/2,
00180 PixRGB<byte>(curr + PixRGB<byte>(255*val*BRIGHTNESS,255*val*BRIGHTNESS, 0)) );
00181
00182 drawHalfLine(outputImage, Point2D<int>(x*OUT_SCALE_FACT, y*OUT_SCALE_FACT), -theta, OUT_SCALE_FACT/2,
00183 PixRGB<byte>(curr + PixRGB<byte>(255*val*BRIGHTNESS,255*val*BRIGHTNESS, 0)) );
00184 }
00185
00186
00187 }
00188 }
00189 }
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 drawCross(outputImage, attentionPoint*OUT_SCALE_FACT, PixRGB<byte>(255,0,0));
00207
00208
00209
00210
00211 char buffer[20];
00212 sprintf(buffer,"(%d, %d)", attentionPoint.i, attentionPoint.j);
00213
00214
00215 flipVertical(outputImage);
00216
00217
00218 writeText(outputImage, Point2D<int>(attentionPoint.i*OUT_SCALE_FACT+5, outputImage.getHeight() - attentionPoint.j*OUT_SCALE_FACT+15), buffer, PixRGB<byte>(255,0,0), PixRGB<byte>(0,0,0), SimpleFont::FIXED(6), false);
00219
00220
00221 window1->drawImage(outputImage,0,0);
00222 window1->drawImage(panelImage,outputImage.getWidth(),0);
00223
00224
00225 key = window1->getLastKeyPress();
00226
00227
00228 switch(key) {
00229 case -122:
00230 attentionPoint.j++;
00231 break;
00232 case -123:
00233 attentionPoint.j--;
00234 break;
00235 case -125:
00236 attentionPoint.i--;
00237 break;
00238 case -124:
00239 attentionPoint.i++;
00240 break;
00241 case 26:
00242 initDataSet1(V2, attentionPoint, k);
00243 break;
00244 case 27:
00245 initDataSet2(V2, attentionPoint, k);
00246 break;
00247 case 28:
00248 initDataSet3(V2, attentionPoint, k);
00249 break;
00250 case 29:
00251 initDataSet4(V2, attentionPoint, k);
00252 break;
00253 case 31:
00254 initDataSet5(V2, attentionPoint, k);
00255 break;
00256 }
00257
00258 Point2D<int> p;
00259 p = window1->getLastMouseClick();
00260 if (p.isValid()) {
00261
00262 Point2D<int> panelPoint = Point2D<int>(p.i-OUTPUT_RES, p.j);
00263 if(but_Data1.inBounds(panelPoint)) {
00264 initDataSet1(V2, attentionPoint, k);
00265 }
00266 if(but_Data2.inBounds(panelPoint)) {
00267 initDataSet2(V2, attentionPoint, k);
00268 }
00269 if(but_Data3.inBounds(panelPoint)) {
00270 initDataSet3(V2, attentionPoint, k);
00271 }
00272 if(but_Data4.inBounds(panelPoint)) {
00273 initDataSet4(V2, attentionPoint, k);
00274 }
00275 if(but_Data5.inBounds(panelPoint)) {
00276 initDataSet5(V2, attentionPoint, k);
00277 }
00278 if(but_Quit.inBounds(panelPoint)) {
00279 LINFO("Qutting... Thanks!");
00280 exit(0);
00281 }
00282
00283 else if(p.i < OUTPUT_RES) {
00284 p/=OUT_SCALE_FACT;
00285
00286 p.j = MAP_SIZE-p.j;
00287 attentionPoint = p;
00288 }
00289 }
00290 } while(key != 20);
00291 }
00292
00293
00294
00295
00296 float M(Image<float> WeightKernel, float theta, Point2D<int> i, Point2D<int> att) {
00297
00298 if(i.distance(att) > WeightKernel.getWidth()/2 || i.distance(att) == 0)
00299 return 0.0F;
00300
00301 float theta_prime = beta(i,att);
00302
00303 if(theta_prime == theta || (theta_prime >= theta + PI -.01 && theta_prime <= theta+PI+.01) || (theta_prime >= theta - PI -.01 && theta_prime <= theta-PI+.01))
00304 return 0.0f;
00305
00306 if((theta <= PI && theta_prime >= theta && theta_prime <= theta+PI) ||
00307 (theta > PI && (theta_prime >= theta || theta_prime < theta-PI)))
00308 return 0;
00309 else {
00310 return WeightKernel.getVal(WeightKernel.getWidth()/2 + abs(i.i - att.i),WeightKernel.getHeight()/2 + abs(i.j - att.j));
00311 }
00312 }
00313
00314
00315
00316 float beta(Point2D<int> i, Point2D<int> j) {
00317
00318 if(j.j-i.j>=0)
00319 return atan2(j.j - i.j, j.i - i.i);
00320 else
00321 return 2.0f*PI + atan2(j.j - i.j, j.i - i.i);
00322 }
00323
00324
00325
00326 template <class T>
00327 void flipVertical(Image <T> &Image) {
00328 T temp;
00329
00330 for(int x = 0; x<Image.getWidth(); x++) {
00331 for(int y=0; y<Image.getHeight()/2; y++) {
00332 temp = Image.getVal(x,Image.getHeight() - y - 1);
00333 Image.setVal(x,Image.getHeight() - y - 1, Image.getVal(x,y));
00334 Image.setVal(x,y,temp);
00335 }
00336 }
00337 }
00338
00339
00340
00341
00342 void initDataSet1(vector< Image<float> > &V2, Point2D<int> &attentionPoint, float &k) {
00343 int theta_index = THETA_LEVELS/4;
00344 int theta_index2 = THETA_LEVELS*3/4;
00345 Dims d = V2[0].getDims();
00346
00347 k = 7.0f;
00348
00349
00350 for(int i=0; i<THETA_LEVELS; i++)
00351 V2[i].clear();
00352
00353
00354
00355 drawLine(V2[theta_index], Point2D<int>(d.w()/2,0), Point2D<int>(d.w()/2,d.h()), 1.0F);
00356
00357
00358
00359 drawLine(V2[theta_index2], Point2D<int>(d.w()/2,0), Point2D<int>(d.w()/2,d.h()), 1.0F);
00360
00361
00362
00363 attentionPoint = Point2D<int>(int(d.w()/2+d.w()*.05), d.h()/2);
00364 }
00365
00366
00367
00368 void initDataSet2(vector< Image<float> > &V2, Point2D<int> &attentionPoint, float &k) {
00369 int theta_down_right = THETA_LEVELS/8;
00370 int theta_up_left = THETA_LEVELS*5/8;
00371 Dims d = V2[0].getDims();
00372
00373 k = 7.0f;
00374
00375
00376 for(int i=0; i<THETA_LEVELS; i++)
00377 V2[i].clear();
00378
00379
00380
00381 drawLine(V2[theta_up_left], Point2D<int>(0,0), Point2D<int>(d.w()-1,d.h()-1), 1.0F);
00382
00383
00384
00385 drawLine(V2[theta_down_right], Point2D<int>(0,0), Point2D<int>(d.w()-1,d.h()-1), 1.0F);
00386
00387
00388
00389 attentionPoint = Point2D<int>(d.w()/2, int(d.h()/2+d.h()*.05));
00390 }
00391
00392
00393
00394
00395 void initDataSet3(vector< Image<float> > &V2, Point2D<int> &attentionPoint, float &k) {
00396
00397 Dims d = V2[0].getDims();
00398
00399 int theta_down = 0;
00400 int theta_right = THETA_LEVELS/4;
00401 int theta_up = THETA_LEVELS/2;
00402 int theta_left = THETA_LEVELS*3/4;
00403
00404 Point2D<int> topRight = Point2D<int>(d.w()*3/4, d.h()*3/4);
00405 Point2D<int> topLeft = Point2D<int>(d.w()/4, d.h()*3/4);
00406 Point2D<int> bottomRight = Point2D<int>(d.w()*3/4, d.h()/4);
00407 Point2D<int> bottomLeft = Point2D<int>(d.w()/4, d.h()/4);
00408
00409 k = 7.0f;
00410
00411
00412 for(int i=0; i<THETA_LEVELS; i++)
00413 V2[i].clear();
00414
00415
00416 drawLine(V2[theta_right], bottomRight, topRight, 1.0F);
00417
00418 drawLine(V2[theta_left], bottomRight, topRight, 1.0F);
00419
00420
00421 drawLine(V2[theta_up],topLeft, topRight, 1.0F);
00422
00423 drawLine(V2[theta_down],topLeft, topRight, 1.0F);
00424
00425
00426 drawLine(V2[theta_right],topLeft, bottomLeft, 1.0F);
00427
00428 drawLine(V2[theta_left],topLeft, bottomLeft, 1.0F);
00429
00430
00431 drawLine(V2[theta_up],bottomLeft, bottomRight, 1.0F);
00432
00433 drawLine(V2[theta_down],bottomLeft, bottomRight, 1.0F);
00434
00435 attentionPoint = Point2D<int>(d.w()/2, d.h()/2);
00436 }
00437
00438
00439
00440 void initDataSet4(vector< Image<float> > &V2, Point2D<int> &attentionPoint, float &k) {
00441 int theta_down = 0;
00442 int theta_right = THETA_LEVELS/4;
00443 int theta_up = THETA_LEVELS/2;
00444 int theta_left = THETA_LEVELS*3/4;
00445
00446 Dims d = V2[0].getDims();
00447
00448 k = 2.5f;
00449
00450
00451 for(int i=0; i<THETA_LEVELS; i++)
00452 V2[i].clear();
00453
00454 drawLine(V2[theta_up], Point2D<int>(d.w()/8,d.h()*3/8), Point2D<int>(d.w()*7/8,d.h()*3/8), 1.0F);
00455 drawLine(V2[theta_down], Point2D<int>(d.w()/8,d.h()*3/8), Point2D<int>(d.w()*7/8,d.h()*3/8), 1.0F);
00456
00457 drawLine(V2[theta_up], Point2D<int>(d.w()/8,d.h()*5/8), Point2D<int>(d.w()*7/8,d.h()*5/8), 1.0F);
00458 drawLine(V2[theta_down], Point2D<int>(d.w()/8,d.h()*5/8), Point2D<int>(d.w()*7/8,d.h()*5/8), 1.0F);
00459
00460 drawLine(V2[theta_left], Point2D<int>(d.w()/8,d.h()*3/8), Point2D<int>(d.w()/8,d.h()*5/8), 1.0F);
00461 drawLine(V2[theta_right], Point2D<int>(d.w()/8,d.h()*3/8), Point2D<int>(d.w()/8,d.h()*5/8), 1.0F);
00462
00463 drawLine(V2[theta_left], Point2D<int>(d.w()*7/8,d.h()*3/8), Point2D<int>(d.w()*7/8,d.h()*5/8), 1.0F);
00464 drawLine(V2[theta_right], Point2D<int>(d.w()*7/8,d.h()*3/8), Point2D<int>(d.w()*7/8,d.h()*5/8), 1.0F);
00465
00466
00467
00468 drawLine(V2[theta_left], Point2D<int>(d.w()*3/8, d.h()/8), Point2D<int>(d.w()*3/8,d.h()*7/8), 1.0F);
00469 drawLine(V2[theta_right], Point2D<int>(d.w()*3/8, d.h()/8), Point2D<int>(d.w()*3/8,d.h()*7/8), 1.0F);
00470
00471 drawLine(V2[theta_left], Point2D<int>(d.w()*5/8, d.h()/8), Point2D<int>(d.w()*5/8,d.h()*7/8), 1.0F);
00472 drawLine(V2[theta_right], Point2D<int>(d.w()*5/8, d.h()/8), Point2D<int>(d.w()*5/8,d.h()*7/8), 1.0F);
00473
00474 drawLine(V2[theta_up], Point2D<int>(d.w()*3/8,d.h()/8), Point2D<int>(d.w()*5/8,d.h()/8), 1.0F);
00475 drawLine(V2[theta_down], Point2D<int>(d.w()*3/8,d.h()/8), Point2D<int>(d.w()*5/8,d.h()/8), 1.0F);
00476
00477 drawLine(V2[theta_up], Point2D<int>(d.w()*3/8,d.h()*7/8), Point2D<int>(d.w()*5/8,d.h()*7/8), 1.0F);
00478 drawLine(V2[theta_down], Point2D<int>(d.w()*3/8,d.h()*7/8), Point2D<int>(d.w()*5/8,d.h()*7/8), 1.0F);
00479
00480
00481 attentionPoint = Point2D<int>(d.w()/2, int(d.h()/2+d.h()*.05));
00482 }
00483
00484
00485
00486
00487 void initDataSet5(vector< Image<float> > &V2, Point2D<int> &attentionPoint, float &k) {
00488
00489 Dims d = V2[0].getDims();
00490
00491 int x1 = d.w()/12;
00492 int x4 = d.w()/3;
00493 int x8 = d.w()*8/12;
00494 int x11 = d.w()*11/12;
00495
00496 k = 4.0f;
00497
00498
00499 for(int i=0; i<THETA_LEVELS; i++)
00500 V2[i].clear();
00501
00502 drawLine(V2[THETA_LEVELS*3/8], Point2D<int>(x1,x11), Point2D<int>(x4,x8), 1.0F);
00503 drawLine(V2[THETA_LEVELS*7/8], Point2D<int>(x1,x11), Point2D<int>(x4,x8), 1.0F);
00504
00505 drawLine(V2[THETA_LEVELS/4], Point2D<int>(x4,x8), Point2D<int>(x4,x4), 1.0F);
00506 drawLine(V2[THETA_LEVELS*3/4], Point2D<int>(x4,x8), Point2D<int>(x4,x4), 1.0F);
00507
00508 drawLine(V2[THETA_LEVELS/8], Point2D<int>(x4,x4), Point2D<int>(x1,x1), 1.0F);
00509 drawLine(V2[THETA_LEVELS*5/8], Point2D<int>(x4,x4), Point2D<int>(x1,x1), 1.0F);
00510
00511 drawLine(V2[THETA_LEVELS/8], Point2D<int>(d.w()-x1,x11), Point2D<int>(d.w()-x4,x8), 1.0F);
00512 drawLine(V2[THETA_LEVELS*5/8], Point2D<int>(d.w()-x1,x11), Point2D<int>(d.w()-x4,x8), 1.0F);
00513
00514 drawLine(V2[THETA_LEVELS/4], Point2D<int>(d.w()-x4,x8), Point2D<int>(d.w()-x4,x4), 1.0F);
00515 drawLine(V2[THETA_LEVELS*3/4], Point2D<int>(d.w()-x4,x8), Point2D<int>(d.w()-x4,x4), 1.0F);
00516
00517 drawLine(V2[THETA_LEVELS*3/8], Point2D<int>(d.w()-x4,x4), Point2D<int>(d.w()-x1,x1), 1.0F);
00518 drawLine(V2[THETA_LEVELS*7/8], Point2D<int>(d.w()-x4,x4), Point2D<int>(d.w()-x1,x1), 1.0F);
00519 }
00520
00521
00522 template <class T>
00523 void drawHalfLine(Image<T>& dst,
00524 const Point2D<int>& pos, float ori, float len, const T col,
00525 const int rad = 1)
00526 {
00527
00528 GVX_TRACE(__PRETTY_FUNCTION__);
00529 ASSERT(dst.initialized());
00530
00531 int x1 = int(cos(ori)*len);
00532 int y1 = int(sin(ori)*len);
00533
00534 Point2D<int> p1 = pos;
00535 Point2D<int> p2(pos.i+x1, pos.j-y1);
00536
00537 drawLine(dst, p1, p2, col, rad);
00538
00539 }
00540