00001
00002
00003
00004
00005
00006
00007
00008 #ifndef V2_H
00009 #define V2_H
00010
00011 #define PI 3.14159265f
00012
00013
00014
00015 #define alpha_x 1.0f
00016 #define alpha_y 1.0f
00017 #define x_th 1.0f
00018 #define x_sat 2.0f
00019 #define y_th1 1.0f
00020 #define y_th2 1.2f
00021 #define g1 0.21f
00022 #define g2 2.5f
00023 #define y_sat 300.0f
00024 #define I_o 0.1f
00025 #define I_c 1.0f
00026 #define THETA_LEVELS 24
00027
00028 #include "Image/Point2D.H"
00029 #include "Image/Image.H"
00030 #include "Image/Pixels.H"
00031 #include "Raster/Raster.H"
00032 #include <vector>
00033 #include <math.h>
00034
00035
00036 using namespace std;
00037
00038 class V2 {
00039 public:
00040 V2(Dims size);
00041
00042
00043 void step();
00044
00045 void setInput(vector< Image<float> > input);
00046
00047
00048
00049 float g_x(float x);
00050 float g_y(float y);
00051 float psi(float theta);
00052 float tau();
00053 float I_normalization(Point2D<int> i, int theta_index);
00054 float phi(float x, float y);
00055 float beta(Point2D<int> i, Point2D<int> j);
00056 float sign(float x);
00057 float theta_one(Point2D<int> i, int i_theta_index, Point2D<int> j);
00058 float theta_two(Point2D<int> i, Point2D<int> j, int j_theta_index);
00059 float theta_one_prime(Point2D<int> i, int i_theta_index, Point2D<int> j);
00060 float theta_two_prime(Point2D<int> i, Point2D<int> j, int j_theta_index);
00061 float theta_plus(float theta_a, float theta_b);
00062 float theta_minus(float theta_a, float theta_b);
00063 void theta_a_b(float &theta_a, float &theta_b, Point2D<int> i, Point2D<int> j, int i_theta_index, int j_theta_index);
00064 float f_1(float d);
00065 float f_2(float d);
00066 float f_T(float d);
00067 float W(Point2D<int> i, int i_theta_index, Point2D<int> j, int j_theta_index);
00068 float J(Point2D<int> i, int i_theta_index, Point2D<int> j, int j_theta_index);
00069 float sumPsiGy(Point2D<int> i, int theta_index);
00070 float sumJGx(Point2D<int> i, int theta_index);
00071 float sumWGx(Point2D<int> i, int theta_index);
00072
00073 float ind2rad(int theta_index);
00074
00075
00076 private:
00077
00078
00079 vector< Image<float> > itsX;
00080 vector< Image<float> > itsY;
00081 vector< Image<float> > itsXprime;
00082 vector< Image<float> > itsYprime;
00083
00084
00085 vector< Image<float> > I;
00086
00087 Dims itsDims;
00088 int t;
00089 };
00090
00091
00092 V2::V2(Dims size) {
00093 itsDims = size;
00094 itsX.resize(THETA_LEVELS, Image<float>(size, ZEROS));
00095 itsY.resize(THETA_LEVELS, Image<float>(size, ZEROS));
00096 itsXprime.resize(THETA_LEVELS, Image<float>(size, ZEROS));
00097 itsYprime.resize(THETA_LEVELS, Image<float>(size, ZEROS));
00098
00099 t=0;
00100
00101
00102 srand((unsigned) (time(0)));
00103 }
00104
00105 void V2::setInput(vector < Image<float> > input) {
00106 I = input;
00107 }
00108
00109
00110
00111 void V2::step() {
00112 float xprime, yprime;
00113
00114 for(int theta_index=0; theta_index<THETA_LEVELS; theta_index++) {
00115 for(int i=0; i<itsDims.w();i++) {
00116 for(int j=0; j<itsDims.h(); j++) {
00117 xprime = -alpha_x*itsX[theta_index].getVal(i,j) - g_y(itsY[theta_index].getVal(i,j)) - sumPsiGy(Point2D<int>(i,j), theta_index) + sumJGx(Point2D<int>(i,j),theta_index) + + I_o + + I_normalization(Point2D<int>(i,j),theta_index);
00118 yprime = -alpha_y*itsY[theta_index].getVal(i,j) + g_x(itsX[theta_index].getVal(i,j)) + sumWGx(Point2D<int>(i,j), theta_index) + I_c ;
00119
00120 itsXprime[theta_index].setVal(i,j,xprime);
00121 itsYprime[theta_index].setVal(i,j,yprime);
00122 }
00123 }
00124 }
00125
00126 for(int theta_index=0; theta_index<THETA_LEVELS; theta_index++) {
00127 itsX[theta_index] += itsXprime[theta_index];
00128 itsY[theta_index] += itsYprime[theta_index];
00129 }
00130
00131 t++;
00132 }
00133
00134 float V2::sumPsiGy(Point2D<int> i, int theta_index) {
00135 float sum = 0;
00136
00137 for(int d_theta_index=1; d_theta_index<THETA_LEVELS; d_theta_index++) {
00138 for(int x=0; x<itsDims.w();x++) {
00139 for(int y=0; y<itsDims.h(); y++) {
00140 sum += psi(ind2rad(d_theta_index)) * g_y(itsY[((theta_index + d_theta_index)%THETA_LEVELS)].getVal(i));
00141 }
00142 }
00143 }
00144 return sum;
00145 }
00146
00147
00148 float V2::sumJGx(Point2D<int> i, int theta_index) {
00149 float sum = 0;
00150
00151 for(int x=0; x<itsDims.w(); x++) {
00152 for(int y=0; y<itsDims.h(); y++) {
00153 if(Point2D<int>(x,y) == i) continue;
00154 for(int theta_prime_index = 0; theta_prime_index < THETA_LEVELS; theta_prime_index++) {
00155 sum += J(i, theta_index, Point2D<int>(x,y), theta_prime_index) * g_x(itsX[theta_prime_index].getVal(x,y) * (t - tau()));
00156 }
00157 }
00158 }
00159 return sum;
00160 }
00161
00162
00163 float V2::sumWGx(Point2D<int> i, int theta_index) {
00164 float sum = 0;
00165 for(int x=0; x<itsDims.w(); x++) {
00166 for(int y=0; y<itsDims.h(); y++) {
00167 if(i == Point2D<int>(x,y)) continue;
00168 for(int theta_prime_index = 0; theta_prime_index < THETA_LEVELS; theta_prime_index++) {
00169 sum += W(i, theta_index, Point2D<int>(x,y),theta_prime_index) * g_x(itsX[theta_prime_index].getVal(x,y)*(t-tau()));
00170 }
00171 }
00172 }
00173 return sum;
00174 }
00175
00176
00177
00178 float V2::ind2rad(int theta_index) {
00179 return (theta_index/THETA_LEVELS)*(2.0f*PI);
00180 }
00181
00182 float V2::g_x(float x) {
00183 if(x < x_th)
00184 return 0.0f;
00185 else if(x >= x_th && x <= x_sat)
00186 return x - x_th;
00187 else if(x > x_sat)
00188 return x_sat - x_th;
00189 else {
00190 LERROR("ERROR! x out of bounds");
00191 return -1.0f;
00192 }
00193 }
00194
00195 float V2::g_y(float y) {
00196 if(y < y_th1)
00197 return 0.0f;
00198 else if(y >= y_th1 && y <= y_th2)
00199 return g1*(y - y_th1);
00200 else if(y >= y_th2 && y <= y_sat)
00201 return g2*(y - y_th2) + g1*(y_th2 - y_th1);
00202 else if(y > y_sat)
00203 return g2*(y_sat - y_th2) + g1*(y_th2 - y_th1);
00204 else {
00205 LERROR("ERROR! y out of bounds");
00206 return -1.0f;
00207 }
00208 }
00209
00210 float V2::psi(float theta) {
00211 if(fabs(theta) == PI/12.0f)
00212 return 0.8f;
00213 if(fabs(theta) == PI/6.0f)
00214 return 0.1f;
00215 else
00216 return 0.0f;
00217 }
00218
00219 float V2::tau() {
00220 return rand()/(float(RAND_MAX)+1.0f)*(1.0f - 0.8f)+0.8f;
00221 }
00222
00223 float V2::I_normalization(Point2D<int> i, int theta_index) {
00224
00225 float a_hat = 0.0f;
00226 Point2D<int> index;
00227
00228 for(int _x = i.i-2; _x < i.i+2; _x++) {
00229 for(int _y = i.j-2; _y < i.j+2; _y++) {
00230 index = Point2D<int>(_x, _y);
00231 index.clampToDims(itsDims);
00232 a_hat += itsX[theta_index].getVal(index);
00233 }
00234 }
00235
00236 return pow(a_hat, 2.0f)/128.0f;
00237 }
00238
00239 float V2::phi(float x, float y) {
00240 float diff = x-y;
00241
00242 if(diff > -PI && diff <= PI) {
00243 return diff;
00244 }
00245 else if(diff <= -PI) {
00246 return diff + 2.0f*PI;
00247 }
00248 else if(diff > PI) {
00249 return diff - 2.0f*PI;
00250 }
00251 LERROR("Diff Out Of Bounds!");
00252 exit(0);
00253 return 1.0f;
00254
00255 }
00256
00257 float V2::beta(Point2D<int> i, Point2D<int> j) {
00258 float beta;
00259
00260 float o = j.j - i.j;
00261 float a = j.i - i.i;
00262
00263
00264
00265
00266 if(a == 0.0f) {
00267 if(o > 0.0f)
00268 return PI/2.0f;
00269 else
00270 return 3.0f*PI/2.0f;
00271 }
00272
00273 beta = atan(o/a);
00274 if(o > 0.0f && a < 0.0f) {
00275 beta = PI+beta;
00276 }
00277 else if(o <= 0.0f && a < 0.0f) {
00278 beta = PI + beta;
00279 }
00280 else if(o < 0.0f && a > 0.0f) {
00281 beta = 2.0f*PI + beta;
00282 }
00283
00284 return beta;
00285 }
00286
00287 float V2::sign(float x) {
00288 if(x >= 0.0f)
00289 return 1.0f;
00290 else
00291 return -1.0f;
00292 }
00293
00294 float V2::theta_one(Point2D<int> i, int i_theta_index, Point2D<int> j) {
00295 return phi(2.0f*(PI/(float)THETA_LEVELS)*(float)i_theta_index, beta(i,j));
00296 }
00297
00298 float V2::theta_two(Point2D<int> i, Point2D<int> j, int j_theta_index) {
00299 return phi(beta(i,j), 2.0f*(PI/(float)THETA_LEVELS)*(float)j_theta_index);
00300 }
00301
00302 float V2::theta_one_prime(Point2D<int> i, int i_theta_index, Point2D<int> j) {
00303 float _theta_one = theta_one(i,i_theta_index,j);
00304 return sign(_theta_one)*fabs(PI-fabs(_theta_one));
00305 }
00306
00307 float V2::theta_two_prime(Point2D<int> i, Point2D<int> j, int j_theta_index) {
00308 float _theta_two = theta_two(i,j,j_theta_index);
00309 return sign(_theta_two)*fabs(PI-fabs(_theta_two));
00310 }
00311
00312 void V2::theta_a_b(float &theta_a, float &theta_b, Point2D<int> i, Point2D<int> j, int i_theta_index, int j_theta_index) {
00313 float _theta_one = theta_one(i, i_theta_index, j);
00314 float _theta_two = theta_two(i, j, j_theta_index);
00315 float _theta_one_prime = theta_one_prime(i, i_theta_index, j);
00316 float _theta_two_prime = theta_two_prime(i, j, j_theta_index);
00317
00318 if(fabs(_theta_one) + fabs(_theta_two) <= fabs(_theta_one_prime) + fabs(_theta_two_prime)) {
00319 theta_a = _theta_one;
00320 theta_b = _theta_two;
00321 }
00322 else {
00323 theta_a = _theta_one_prime;
00324 theta_b = _theta_two_prime;
00325 }
00326 }
00327
00328 float V2::theta_plus(float theta_a, float theta_b) {
00329 float theta_prime_plus = theta_a + theta_b;
00330
00331 if(theta_prime_plus >= -PI && theta_prime_plus <= PI)
00332 return theta_prime_plus;
00333 else if(theta_prime_plus > PI)
00334 return 2.0f*PI - theta_prime_plus;
00335 else
00336 return -2.0f*PI - theta_prime_plus;
00337 }
00338
00339 float V2::theta_minus(float theta_a, float theta_b) {
00340 float theta_prime_minus = theta_a - theta_b;
00341
00342 if(theta_prime_minus >= -PI && theta_prime_minus <= PI)
00343 return theta_prime_minus;
00344 else if(theta_prime_minus > PI)
00345 return 2.0f*PI - theta_prime_minus;
00346 else
00347 return -2.0f*PI - theta_prime_minus;
00348 }
00349
00350 float V2::f_1(float d) {
00351 if(d > 10.0f || d == 0.0f)
00352 return 0.0f;
00353
00354 return exp(-pow(d/9.0f,2.0f));
00355 }
00356
00357 float V2::f_2(float d) {
00358 if(d > 10.0f || d == 0.0f)
00359 return 0.0f;
00360
00361 return exp(-d/5.0f);
00362 }
00363
00364 float V2::f_T(float d) {
00365 return (11.0f/90.0f)*exp(-d/6.0f);
00366 }
00367
00368
00369 float V2::J(Point2D<int> i, int i_theta_index, Point2D<int> j, int j_theta_index) {
00370 float theta_a, theta_b;
00371 float _theta_plus, _theta_minus;
00372 float d = fabs(i.distance(j));
00373 float ret;
00374
00375
00376 theta_a_b(theta_a, theta_b, i, j, i_theta_index, j_theta_index);
00377
00378 _theta_plus = theta_plus(theta_a, theta_b);
00379 _theta_minus = theta_minus(theta_a, theta_b);
00380
00381
00382
00383 if(d > 0.0f && d <= 2.0f && fabs(theta_a*d) < 0.5f && fabs(theta_b) > PI/3.1f && fabs(theta_b) < 2.0f*PI/3.1f) {
00384
00385 if(theta_b < 0.0f)
00386 return f_T(d)*exp(-2.0f*fabs(theta_a*d));
00387 else
00388 return 0.0f;
00389 }
00390 else if(d > 0.0f && d <= 2.0f && fabs(theta_b*d) < 0.5f && fabs(theta_a) > PI/3.1f && fabs(theta_a) < 2.0f*PI/3.1f) {
00391
00392 if(theta_a < 0.0f)
00393 return 3.0f*f_T(d)*exp(-2.0f*fabs(theta_b*d));
00394 else
00395 return 0.0f;
00396 }
00397
00398
00399
00400 if(fabs(theta_a) <= PI/11.0f && fabs(theta_b) <= PI/11.0f) {
00401
00402 ret = (11.0f/108.0f) * exp(-(3.0f - 2.5f*sign(_theta_plus))*fabs(_theta_plus)/(5.0f*PI) - 2.0f * pow(_theta_minus, 2.0f)/pow(PI, 2.0f))*f_1(d);
00403 }
00404 else if(theta_a >= 0.0f && theta_b >= 0.0f && _theta_plus < PI/2.01f) {
00405
00406 ret = (11.0f/81.0f) * exp(-3.0f*_theta_plus/(5.0f*PI) - 2.0f*pow(_theta_minus,2.0f)/pow(PI,2.0f))/f_2(d);
00407 }
00408 else if(theta_a >= 0.0f && theta_b >= 0.0f && _theta_plus >= PI/2.01f && fabs(_theta_minus) < PI/2.01f) {
00409
00410 ret = (11.0f/81.0f) * exp(-pow((9.0f*_theta_plus)/(8.0f*PI),2.0f) - 2.0f*pow(_theta_minus,2.0f)/pow(PI,2.0f))*f_2(d);
00411 }
00412 else if(theta_a >= 0.0f && theta_b >= 0.0f && _theta_plus >= PI/2.01f && fabs(_theta_minus) >= PI/2.01f) {
00413
00414 ret = (11.0f/81.0f) * exp(-pow(9.0f*_theta_plus/(8.0f*PI),2.0f) - 0.5f*pow((_theta_minus/(PI/2.0f)),6.0f))*f_2(d);
00415 }
00416 else if(theta_a <= 0.0f && theta_b <= 0.0f) {
00417
00418 ret = (11.0f/81.0f) * exp(-4.0f*pow(_theta_plus/PI,2.0f) - 9.0f*pow(_theta_minus, 2.0f)/pow(PI, 2.0f))*f_2(d);
00419 }
00420 else if(theta_a*theta_b <= 0.0f && fabs(_theta_minus) < PI/2.01f) {
00421
00422 ret = (11.0f/81.0f) * exp(11.5f*sign(_theta_plus)*pow(_theta_plus,2.0f)/pow(PI,2.0f) - 14.0f*pow(_theta_minus,2.0f)/pow(PI,2.0f))*f_2(d);
00423 }
00424 else if(theta_a*theta_b <= 0.0f && fabs(_theta_minus) >= PI/2.01f) {
00425
00426 ret = (11.0f/81.0f) * exp(11.5f*sign(_theta_plus)*pow(_theta_plus,2.0f)/pow(PI,2.0f) - (15.0f/4.0f)*pow((2.0f*_theta_minus/PI),6.0f))*f_2(d);
00427 }
00428 else {
00429 LERROR("theta_a and theta_b slipped through the cracks! \n theta_a=%f \n theta_b=%f \n theta_plus=%f \n theta_minus=%f\n", theta_a, theta_b, _theta_plus, _theta_minus);
00430 LINFO("ERROR!");
00431 exit(0);
00432 return 1.0f;
00433 }
00434
00435
00436
00437
00438 return ret;
00439 }
00440
00441 float V2::W(Point2D<int> i, int i_theta_index, Point2D<int> j, int j_theta_index) {
00442 float theta_a, theta_b, c;
00443 float d = fabs(i.distance(j));
00444
00445 theta_a_b(theta_a, theta_b, i, j, i_theta_index, (j_theta_index+THETA_LEVELS/2)%THETA_LEVELS);
00446
00447 if(d > 0.0f && d <= 2.0f && fabs(theta_a*d) < 0.5f && fabs(theta_b) > PI/3.1f && fabs(theta_b) < 2.0f*PI/3.1f) {
00448 if(theta_b < 0.0f)
00449 return 0.0f;
00450
00451 else
00452 return 0.0f;
00453 }
00454 else if(d > 0.0f && d <= 2.0f && fabs(theta_b*d) < 0.5f && fabs(theta_a) > PI/3.1f && fabs(theta_a) < 2.0f*PI/3.1f) {
00455 if(theta_a < 0.0f)
00456 return 0.0f;
00457
00458 else
00459 return 0.0f;
00460 }
00461
00462
00463 if(fabs(theta_a) <= PI/11.0f && fabs(theta_b) <= PI/11.0f)
00464 c = 0.0147f;
00465 else
00466 c = 0.02646f;
00467
00468 return c*(J(i, (i_theta_index+THETA_LEVELS/2)%THETA_LEVELS, j, j_theta_index) + J(i, i_theta_index, j, (j_theta_index+THETA_LEVELS/2)%THETA_LEVELS)/J(i, 0, Point2D<int>(i.i+1, i.j), 0));
00469
00470
00471 }
00472
00473 #endif