00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "RFieldSpecialist.h"
00011
00012
00013 RFieldSpecialist::RFieldSpecialist(RasterImageProcessor &processor,RasterStrategy &strat):
00014 RasterSpecialist(processor), edgeScanner(processor)
00015 {
00016 strategy = &strat;
00017
00018 segments_img.reserve(3);
00019
00020 defaultParam = new processParam();
00021
00022 lineInside = LinesPercept::numberOfLineTypes;
00023
00024 }
00025
00026 RFieldSpecialist::~RFieldSpecialist()
00027 {
00028 delete defaultParam;
00029 }
00030
00031 int RFieldSpecialist::getType()
00032 {
00033 return __RFieldSpecialist;
00034 }
00035
00036 void RFieldSpecialist::init()
00037 {
00038 preScanNeeded = true;
00039 postScanNeeded = false;
00040
00041 lst_pts.clear();
00042
00043 int i;
00044 for (i = 0; i< (int)segments_img.size(); ++i)
00045 segments_img[i].clear();
00046 }
00047
00048 void RFieldSpecialist::invokeOnPreScan(int x,int y){
00049
00050 if (!strategy->insideField) temp = Vector2<int>(x,y);
00051 else{
00052
00053 point tmp2 = Vector2<int>(x,y);
00054
00055
00056
00057 edgeScanner.threshold = 20;
00058 edgeScanner.scanWest(temp.x,temp.y);
00059 edgeScanner.scanEast(tmp2.x,tmp2.y);
00060
00061 if (tmp2.x - temp.x < 4) return;
00062
00063 horLinePair* lp= new horLinePair(temp,tmp2);
00064
00065 lst_pts.push_front(lp);
00066
00067 LINE(imageProcessor_ground,
00068 lp->pt1().x,lp->pt1().y, lp->pt2().x,lp->pt2().y,
00069 0.5, Drawings::ps_solid, Drawings::gray);
00070
00071 }
00072 }
00073
00074 int RFieldSpecialist::id(LinesPercept::LineType l) {
00075 switch (l) {
00076 case LinesPercept::field : return 0;
00077 case LinesPercept::border : return 1;
00078 case LinesPercept::yellowGoal : return 2;
00079 case LinesPercept::skyblueGoal : return 3;
00080 default : return -1;
00081 }
00082 }
00083
00084 LinesPercept::LineType RFieldSpecialist::id(int i) {
00085 switch (i) {
00086 case 0 : return LinesPercept::field ;
00087 case 1 : return LinesPercept::border;
00088 case 2 : return LinesPercept::yellowGoal;
00089 case 3 : return LinesPercept::skyblueGoal;
00090 default : return LinesPercept::field;
00091 }
00092 }
00093
00094 void RFieldSpecialist::invokeOnPostScan(int x,int y) {}
00095
00096
00097 void RFieldSpecialist::addLinePoint(LinesPercept::LineType line , point & v, int& p) {
00098
00099 segments_img[id(line)].push_front(new edge(v,(unsigned short)p));
00100
00101 }
00102
00103
00104 bool isEqual (double & a1, double & a2, float tol) {
00105 return (fabs(a1-a2)<=tol);
00106 }
00107
00108
00109 void RFieldSpecialist::fusionLines(lstLinePair& lst) {
00110
00111 lstLinePair::iterator it, it2;
00112 double angle;
00113
00114
00115 for (it = lst.front();!it.end();++it) {
00116
00117 it2 = lst.front();
00118
00119 while(!it2.end() && it2->getNext() && it2->getNext()!= *it) {
00120
00121 angle = (int)theta2(*it, it2->getNext())%180;
00122
00123 Vector2<double> v = mil (**it2);
00124
00125 if (angle<=8 || angle >= 172 &&
00126 Geometry::getDistanceToLine(makeLine(*it),v) <1) {
00127
00128 point p1, p2;
00129
00130 if (Geometry::distance(it->p1, it2->getNext()->p1) >
00131 Geometry::distance(it->p1, it2->getNext()->p2))
00132 p1 = it2->getNext()->p1;
00133
00134 else p1 = it2->getNext()->p2;
00135
00136 if (Geometry::distance(it2->getNext()->p1, it->p1) >
00137 Geometry::distance(it2->getNext()->p1, it->p2))
00138 p2 = it->p1;
00139
00140 else p2 = it->p2;
00141
00142 it->p1 = p1;
00143 it->p2 = p2;
00144
00145 lst.erase(*it2);
00146
00147 } else
00148 if(!++it2) break;
00149
00150 }
00151 }
00152 }
00153
00154 bool RFieldSpecialist::makeLines(lstFig& lst, lstLinePair& lines,
00155 const processParam* prParam) {
00156
00157 int size_t = -1;
00158 unsigned int min_size = prParam->min_size;
00159 unsigned int step_alpha = prParam->step_alpha;
00160 unsigned int tol_alpha = prParam->tol_alpha;
00161
00162 unsigned int i;
00163
00164 lstFig::iterator first(lst.front());
00165 lstFig::iterator next = first;
00166
00167
00168 if (!(next+=step_alpha)) return false;
00169
00170 unsigned c = lst.getSize();
00171
00172 double * tab_angle = new double[c];
00173 unsigned int * tab_nb = new unsigned int[c];
00174 LinePair2** tab_line = new LinePair2*[c];
00175
00176
00177 for(i= 0;i<c;++i) {tab_line[i] = 0;tab_angle[i]=0;tab_nb[i]=0;}
00178
00179 do {
00180
00181 point p1 = first->toConsider();
00182 point p2 = next->toConsider();
00183
00184 double angle = theta2(p1,p2);
00185
00186 bool too_inclined = (size_t>=0) ?
00187 !isEqual(tab_angle[size_t],angle,(float)tol_alpha) : false;
00188
00189 if (size_t==-1) {
00190
00191 ++size_t;
00192 tab_line[size_t] = new LinePair2(p1,p2);
00193 tab_angle[size_t] = angle;
00194 tab_nb[size_t] = 1;
00195
00196 } else if (!too_inclined) {
00197
00198 ++tab_nb[size_t];
00199 tab_line[size_t]->p2 = p1;
00200
00201 } else {
00202
00203 if (tab_nb[size_t]<min_size) {
00204 delete tab_line[size_t];
00205 } else {
00206 ++size_t;
00207 }
00208
00209 tab_line[size_t] = new LinePair2(p1, p2);
00210 tab_angle[size_t] = angle;
00211 tab_nb[size_t] = 1;
00212 }
00213
00214 next = ++first;
00215
00216 } while (next+=step_alpha);
00217
00218
00219 bool valid = false;
00220 for (i = 0;i<=(unsigned)size_t;++i) {
00221
00222 if (tab_nb[i] >= min_size) {
00223
00224 valid = true;
00225 lines.push_front(tab_line[i]);
00226 } else {
00227
00228 delete tab_line[i];
00229
00230 }
00231 }
00232
00233 delete [] tab_angle;
00234 delete [] tab_line;
00235 delete [] tab_nb;
00236
00237 return valid;
00238
00239 }
00240
00241
00242 void RFieldSpecialist::executePostProcessing(){
00243
00244 if (lst_pts.getSize() < 4) return;
00245
00246 createLinearSegment(lst_pts);
00247
00248 lstFig::iterator it = lst_pts.front();
00249
00250 lstLinePair res;
00251
00252 if (!makeLines(lst_pts, res, defaultParam)) return;
00253
00254 lstLinePair::iterator cur2 = res.front();
00255
00256 while (!cur2.end()) {
00257
00258 LINE(imageProcessor_ground,
00259 cur2->p1.x, cur2->p1.y, cur2->p2.x,cur2->p2.y,
00260 1, Drawings::ps_solid,
00261 Drawings::white);
00262
00263 ++cur2;
00264 }
00265
00266 fusionLines(res);
00267
00268 checkRamp(res);
00269
00270 res.clear();
00271 }
00272
00273 void RFieldSpecialist::drawCross(goal_line g, point& v) {
00274
00275 switch(g) {
00276 case YELLOW :
00277 LINE(imageProcessor_ground,
00278 v.x-4,v.y-4,v.x+4, v.y+4,
00279 2, Drawings::ps_solid, Drawings::yellow);
00280 LINE(imageProcessor_ground,
00281 v.x-4,v.y+4,v.x+4, v.y-4,
00282 2, Drawings::ps_solid, Drawings::yellow);
00283 break;
00284 case SKYBLUE:
00285 LINE(imageProcessor_ground,
00286 v.x-4,v.y-4,v.x+4, v.y+4,
00287 2, Drawings::ps_solid, Drawings::blue);
00288 LINE(imageProcessor_ground,
00289 v.x-4,v.y+4,v.x+4, v.y-4,
00290 2, Drawings::ps_solid, Drawings::blue);
00291 break;
00292 default:
00293 LINE(imageProcessor_ground,
00294 v.x-4,v.y-4,v.x+4, v.y+4,
00295 2, Drawings::ps_solid, Drawings::black);
00296 LINE(imageProcessor_ground,
00297 v.x-4,v.y+4,v.x+4, v.y-4,
00298 2, Drawings::ps_solid, Drawings::black);
00299 }
00300
00301 }
00302 void RFieldSpecialist::drawCircle(goal_line g, point& v) {
00303 switch(g) {
00304 case YELLOW :
00305 CIRCLE(imageProcessor_ground,v.x, v.y, 5, 1,
00306 Drawings::ps_solid, Drawings::yellow);
00307 break;
00308 case SKYBLUE:
00309 CIRCLE(imageProcessor_ground,v.x, v.y, 5, 1,
00310 Drawings::ps_solid, Drawings::blue);
00311 break;
00312 default:
00313 CIRCLE(imageProcessor_ground,v.x, v.y, 5, 1,
00314 Drawings::ps_solid, Drawings::black);
00315 }
00316 }
00317
00318 void RFieldSpecialist::drawLine(goal_line g, LinePair2& lp) {
00319 switch(g) {
00320 case YELLOW :
00321 LINE(imageProcessor_ground,lp.p1.x, lp.p1.y, lp.p2.x, lp.p2.y, 1,
00322 Drawings::ps_solid, Drawings::yellow);
00323 break;
00324 case SKYBLUE:
00325 LINE(imageProcessor_ground,lp.p1.x, lp.p1.y, lp.p2.x, lp.p2.y, 1,
00326 Drawings::ps_solid, Drawings::blue);
00327 break;
00328 default:
00329 LINE(imageProcessor_ground,lp.p1.x, lp.p1.y, lp.p2.x, lp.p2.y, 1,
00330 Drawings::ps_solid, Drawings::black);
00331 }
00332 }
00333
00334 unsigned int RFieldSpecialist::analyzeLines() {
00335
00336 lstLinePair::iterator it;
00337 double angle;
00338 unsigned i;
00339
00340
00341 double max_length;
00342 LinePair2** max_lines = new LinePair2*[vecLines.size()];
00343
00344 for (i = 1; i<vecLines.size();++i) {
00345
00346 max_lines[i] = 0;
00347 max_length = 0;
00348
00349 for (it = vecLines[i].front();!it.end() ;++it) {
00350
00351 double length = it->getLength();
00352
00353 if (length>max_length) {
00354 max_length = length;
00355 max_lines[i] = *it;
00356 }
00357 }
00358 }
00359
00360 max_lines[0] = 0;
00361 angle = 180;
00362 if (max_lines[1])
00363 for (it = vecLines[0].front();!it.end() ;++it) {
00364
00365 double tmp = 90 - (int)theta2(*it, max_lines[1])%180;
00366 OUTPUT(idText,text, "analyse mil " << tmp);
00367 if (tmp<angle) {
00368 angle = tmp;
00369 max_lines[0] = *it;
00370 }
00371 }
00372
00373 OUTPUT(idText,text, "max analyse mil " << angle);
00374 goal_line seen_goal;
00375
00376 if (max_lines[2]) {
00377 seen_goal = YELLOW;
00378 }
00379 else if (max_lines[3]) {
00380 seen_goal = SKYBLUE;
00381 } else seen_goal = NONE;
00382
00383
00384 for (i = 0; i< vecLines.size(); ++i) {
00385
00386 lstLinePair& lst = vecLines[i];
00387
00388 for (it = lst.front();!it.end() && it->getNext();++it) {
00389
00390 angle = (int)theta2(*it, it->getNext())%180;
00391
00392 if (angle>10 && angle<170) {
00393
00394 point v;
00395 Geometry::Line l1 = makeLine(*it);
00396 Geometry::Line l2 = makeLine(it->getNext());
00397
00398 Geometry::getIntersectionOfLines(l1, l2, v);
00399
00400 drawCross(seen_goal, v);
00401
00402 }
00403 }
00404 }
00405
00406 double size_fact;
00407
00408 if (max_lines[1] ) {
00409
00410 size_fact = (seen_goal==NONE) ? 0 : max_lines[1]->getLength()/max_lines[seen_goal==YELLOW ? 2 : 3]->getLength();
00411
00412 OUTPUT(idText,text, "size fact " << size_fact);
00413
00414 if (size_fact<2.6) {
00415 drawLine(seen_goal, (*max_lines[1]));
00416 } else {
00417 LINE(imageProcessor_ground,
00418 max_lines[1]->p1.x, max_lines[1]->p1.y,
00419 max_lines[1]->p2.x, max_lines[1]->p2.y,
00420 1, Drawings::ps_solid, Drawings::green);
00421 }
00422
00423 if (max_lines[0]) {
00424 point v;
00425
00426 Geometry::getIntersectionOfLines(makeLine(max_lines[0]),makeLine(max_lines[1]), v);
00427
00428 drawCircle(seen_goal, v);
00429 }
00430 }
00431
00432
00433 delete [] max_lines;
00434
00435
00436 return 0;
00437
00438
00439 }
00440
00441 void RFieldSpecialist::checkRamp(lstLinePair & ramp) {
00442
00443 lstLinePair::iterator it2;
00444
00445 double max_length = 0;
00446 LinePair2* max_line = 0;
00447
00448 for (it2 = ramp.front();!it2.end() ;++it2) {
00449
00450 double length = it2->getLength();
00451
00452 if (length>max_length) {
00453 max_length = length;
00454 max_line = *it2;
00455 }
00456 }
00457
00458 if (max_line)
00459 {
00460 LINE(imageProcessor_ground,
00461 max_line->p1.x, max_line->p1.y, max_line->p2.x,max_line->p2.y,
00462 3, Drawings::ps_solid,
00463 Drawings::green);
00464
00465 OUTPUT(idText,text, "angle " << (int)theta2(max_line->p1,max_line->p2)%180);
00466
00467 int px = max_line->p1.y > max_line->p2.y ? max_line->p1.x : max_line->p2.x;
00468 float d = (float)px/(float)rip->maxX;
00469
00470 point pStart;
00471 point pEnd;
00472
00473 if (max_line->p1.y > max_line->p2.y){
00474 pStart=max_line->p1;
00475 pEnd=max_line->p2;
00476 } else {
00477 pStart=max_line->p2;
00478 pEnd=max_line->p1;
00479 }
00480
00481 Vector2<int> relativeStart;
00482 Geometry::calculatePointOnField(
00483 pStart.x,pStart.y,
00484 rip->cameraMatrix,
00485 rip->image.cameraInfo,relativeStart);
00486
00487 Vector2<int> relativeEnd;
00488
00489 Geometry::calculatePointOnField(
00490 pEnd.x,pEnd.y,
00491 rip->cameraMatrix,
00492 rip->image.cameraInfo,
00493 relativeEnd);
00494
00495
00496 rip->specialPercept.ocRedLine.addPercept(
00497 relativeStart,relativeEnd
00498 ,pStart,pEnd,
00499 (int)theta2(max_line->p1,max_line->p2)%180);
00500
00501
00502 OUTPUT(idText,text, "relative position : " << d);
00503
00504 }
00505
00506 }
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646