00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef __REdgeDetection_h_
00010 #define __REdgeDetection_h_
00011
00012 #include "Representations/Perception/Image.h"
00013 #include "Modules/ImageProcessor/ImageProcessor.h"
00014 #include "Modules/ImageProcessor/ImageProcessorTools/ColorCorrector.h"
00015 #include "Modules/ImageProcessor/ImageProcessorTools/SUSANEdgeDetectionLite.h"
00016
00017
00018
00019
00020
00021 class REdgeDetection
00022 {
00023
00024 public:
00025
00026
00027
00028
00029
00030 REdgeDetection(ImageProcessor& processor);
00031
00032
00033 ~REdgeDetection();
00034
00035 int threshold;
00036
00037
00038 int tempX;
00039
00040
00041 int tempY;
00042
00043
00044
00045
00046
00047
00048
00049 bool scanEast(int& x, int& y);
00050
00051
00052
00053
00054
00055
00056 bool scanWest(int& x, int& y);
00057
00058
00059
00060
00061
00062
00063 bool scanNorth(int& x, int& y);
00064
00065
00066
00067
00068
00069
00070
00071 bool scanSouth(int& x, int& y);
00072
00073
00074
00075
00076
00077
00078
00079 bool ballScanEast(int& x, int& y);
00080
00081
00082
00083
00084
00085
00086
00087 bool ballScanWest(int& x, int& y);
00088
00089
00090
00091
00092
00093
00094
00095
00096 bool scan(int& x,int& y,Vector2<double> direction);
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 bool bufferedScan(int& x,int& y,Vector2<double> direction);
00110
00111
00112
00113
00114
00115
00116
00117 bool bufferedScan(int& x,int& y);
00118
00119
00120
00121
00122
00123
00124
00125
00126 bool scanField(int& x,int& y,Vector2<double> direction);
00127
00128
00129
00130
00131
00132
00133
00134 bool scanField(int& x,int& y);
00135
00136
00137
00138
00139
00140
00141
00142 bool scan(int& x,int& y);
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 bool colorScan(int& x,int& y,Vector2<double> direction,colorClass& lastColor);
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 bool colorScan(int& x,int& y,colorClass& lastColor);
00164
00165
00166
00167
00168
00169
00170
00171 bool susanScan(int& x,int& y,Vector2<double> direction);
00172
00173
00174
00175
00176
00177
00178
00179
00180 bool scan(int& x,int& y,int x1,int y1);
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 bool colorScan(int& x,int& y,int x1,int y1,colorClass& lastColor);
00191
00192
00193
00194 inline void setDirection(Vector2<double> dir){
00195 cx = (dir.x<0)? -1 : 1;
00196 cy = (dir.y<0)? -1 : 1;
00197 dx = abs((int)(dir.x * 500.0f));
00198 dy = abs((int)(dir.y * 500.0f));
00199 if (dx>dy){
00200 e = dx - 2*dy;
00201 f = 2*(dx - dy);
00202 g = -2*dy;
00203 }
00204 else{
00205 e = dy - 2*dx;
00206 f = 2*(dy - dx);
00207 g = -2*dx;
00208 }
00209 direction = dir;
00210 }
00211
00212
00213
00214
00215 inline colorClass getColor(int index){
00216 return colorBuffer[index];
00217 }
00218
00219
00220
00221
00222 inline int getRange(int index){
00223 return ranges[index];
00224 }
00225
00226
00227
00228
00229
00230 inline bool isHorizontalEdge(int x, int y){
00231 return horizontalEdgeVote(x,y) > threshold;
00232 }
00233
00234
00235
00236
00237
00238 inline int horizontalEdgeVote(int x,int y){
00239 if (x < 1 || x > ip.image.cameraInfo.resolutionWidth-2) return -1;
00240 int cx1 = x-1;
00241 int cx2 = x+1;
00242 int a1 = ip.image.image[y][0][cx1];
00243 int b1 = ip.image.image[y][1][cx1];
00244 int c1 = ip.image.image[y][2][cx1];
00245 int a2 = ip.image.image[y][0][cx2];
00246 int b2 = ip.image.image[y][1][cx2];
00247 int c2 = ip.image.image[y][2][cx2];
00248
00249 return abs(a1 - a2) + abs(b1 - b2) + abs(c1 - c2);
00250 }
00251
00252
00253
00254
00255
00256 inline bool isVerticalEdge(int x, int y){
00257 return verticalEdgeVote(x,y) > threshold;
00258 }
00259
00260
00261
00262
00263
00264 inline int verticalEdgeVote(int x,int y){
00265 if (y < 1 || y > ip.image.cameraInfo.resolutionHeight-2) return -1;
00266 int cy1 = y-1;
00267 int cy2 = y+1;
00268 int a1 = ip.image.image[cy1][0][x];
00269 int b1 = ip.image.image[cy1][1][x];
00270 int c1 = ip.image.image[cy1][2][x];
00271 int a2 = ip.image.image[cy2][0][x];
00272 int b2 = ip.image.image[cy2][1][x];
00273 int c2 = ip.image.image[cy2][2][x];
00274
00275 return abs(a1 - a2) + abs(b1 - b2) + abs(c1 - c2);
00276 }
00277
00278
00279
00280
00281
00282 inline int ballEdgeVote(int x,int y){
00283
00284 if (x < 1 || x > ip.image.cameraInfo.resolutionWidth-2) return -1;
00285 if (y < 1 || y > ip.image.cameraInfo.resolutionHeight-2) return -1;
00286 int vertical = 0;
00287 int horizontal = 0;
00288 int p1 = x-1;
00289 int p2 = x+1;
00290 int a1 = ip.image.image[y][0][p1];
00291 int b1 = ip.image.image[y][1][p1];
00292 int c1 = ip.image.image[y][2][p1];
00293 int a2 = ip.image.image[y][0][p2];
00294 int b2 = ip.image.image[y][1][p2];
00295 int c2 = ip.image.image[y][2][p2];
00296
00297 horizontal = abs(a1 - a2) + abs(b1 - b2) + abs(c1 - c2);
00298
00299 p1 = y-1;
00300 p2 = y+1;
00301 a1 = ip.image.image[p1][0][x];
00302 b1 = ip.image.image[p1][1][x];
00303 c1 = ip.image.image[p1][2][x];
00304 a2 = ip.image.image[p2][0][x];
00305 b2 = ip.image.image[p2][1][x];
00306 c2 = ip.image.image[p2][2][x];
00307
00308 vertical = abs(a1 - a2) + abs(b1 - b2) + abs(c1 - c2);
00309
00310 return (vertical > horizontal) ? vertical : horizontal;
00311 }
00312
00313
00314
00315
00316
00317 inline int crossEdgeVote(int x,int y){
00318 if (x < 1 || x > ip.image.cameraInfo.resolutionWidth-2) return -1;
00319 if (y < 1 || y > ip.image.cameraInfo.resolutionHeight-2) return -1;
00320 int vertical = 0;
00321 int horizontal = 0;
00322 int p1 = x-1;
00323 int p2 = x+1;
00324 int a1 = ip.image.image[y][0][p1];
00325 int b1 = ip.image.image[y][1][p1];
00326 int c1 = ip.image.image[y][2][p1];
00327 int a2 = ip.image.image[y][0][p2];
00328 int b2 = ip.image.image[y][1][p2];
00329 int c2 = ip.image.image[y][2][p2];
00330
00331 horizontal = abs(a1 - a2) + abs(b1 - b2) + abs(c1 - c2);
00332
00333 p1 = y-1;
00334 p2 = y+1;
00335 a1 = ip.image.image[p1][0][x];
00336 b1 = ip.image.image[p1][1][x];
00337 c1 = ip.image.image[p1][2][x];
00338 a2 = ip.image.image[p2][0][x];
00339 b2 = ip.image.image[p2][1][x];
00340 c2 = ip.image.image[p2][2][x];
00341
00342 vertical = abs(a1 - a2) + abs(b1 - b2) + abs(c1 - c2);
00343
00344 return (vertical > horizontal) ? vertical : horizontal;
00345 }
00346
00347
00348
00349
00350
00351
00352 inline int fieldEdgeVote(int x,int y){
00353 if (x < 1 || x > ip.image.cameraInfo.resolutionWidth-2) return -1;
00354 if (y < 1 || y > ip.image.cameraInfo.resolutionHeight-2) return -1;
00355 int vertical = 0;
00356 int horizontal = 0;
00357 int p1 = x-1;
00358 int p2 = x+1;
00359 int a1 = ip.image.image[y][0][p1];
00360 int b1 = ip.image.image[y][1][p1];
00361 int a2 = ip.image.image[y][0][p2];
00362 int b2 = ip.image.image[y][1][p2];
00363
00364
00365 horizontal = abs(a1 - a2) + abs(b1 - b2);
00366
00367 p1 = y-1;
00368 p2 = y+1;
00369 a1 = ip.image.image[p1][0][x];
00370 b1 = ip.image.image[p1][1][x];
00371 a2 = ip.image.image[p2][0][x];
00372 b2 = ip.image.image[p2][1][x];
00373
00374 vertical = abs(a1 - a2) + abs(b1 - b2);
00375
00376 return (vertical > horizontal) ? vertical : horizontal;
00377 }
00378
00379
00380
00381
00382
00383
00384 inline colorClass getColor(int x,int y){
00385 if (x < 1 || x > ip.image.cameraInfo.resolutionWidth-2) return (colorClass)-1;
00386 if (y < 1 || y > ip.image.cameraInfo.resolutionHeight-2) return (colorClass)-1;
00387
00388 unsigned char cy = ip.image.image[y][0][x];
00389 unsigned char cu = ip.image.image[y][1][x];
00390 unsigned char cv = ip.image.image[y][2][x];
00391 ColorCorrector::correct(x,y,cy,cu,cv);
00392 return ip.colorTable.getColorClass(cy,cu,cv);
00393 }
00394
00395
00396
00397
00398
00399
00400
00401 inline void skip(int& x,int& y){
00402 if (dx>dy){
00403 x+=cx;
00404 if (e<0) {
00405 y+=cy;
00406 e+=f;
00407 }
00408 else {
00409 e+=g;
00410 }
00411 }
00412 else{
00413 y+=cy;
00414 if (e<0) {
00415 x+=cx;
00416 e+=f;
00417 }
00418 else {
00419 e+=g;
00420 }
00421 }
00422 }
00423
00424
00425
00426
00427
00428
00429
00430 inline bool findStart(Vector2<int>& start,const Vector2<double>& dir){
00431 int dx = (int)(dir.x*300 + 0.5);
00432 int dy = (int)(dir.y*300 + 0.5);
00433
00434 Vector2<int> rightBorder(start.x + dx,start.y + dy);
00435
00436 return Geometry::clipLineWithRectangleCohenSutherland(
00437 Vector2<int>(1,1),
00438 Vector2<int>(ip.image.cameraInfo.resolutionWidth -2,ip.image.cameraInfo.resolutionHeight -2),
00439 start,
00440 rightBorder
00441 );
00442 }
00443
00444
00445
00446 inline int getBufferSize(){
00447 return bufferSize;
00448 }
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463 private:
00464
00465
00466 ImageProcessor& ip;
00467
00468
00469 SUSANEdgeDetectionLite susanDetector;
00470
00471 Vector2<double> direction;
00472
00473
00474 int e;
00475
00476 int f;
00477
00478 int g;
00479
00480 int dx;
00481
00482 int dy;
00483
00484 int cx;
00485
00486 int cy;
00487
00488 int bufferSize;
00489
00490 colorClass currentColor;
00491
00492 colorClass lastColor;
00493
00494
00495 int colorRange;
00496
00497
00498
00499
00500 colorClass colorBuffer[20];
00501
00502
00503 int ranges[20];
00504
00505
00506
00507
00508
00509
00510 inline int fastCrossEdgeVote(int x,int y){
00511 int vertical = 0;
00512 int horizontal = 0;
00513 int p1 = x-1;
00514 int p2 = x+1;
00515 int a1 = ip.image.image[y][0][p1];
00516 int b1 = ip.image.image[y][1][p1];
00517 int c1 = ip.image.image[y][2][p1];
00518 int a2 = ip.image.image[y][0][p2];
00519 int b2 = ip.image.image[y][1][p2];
00520 int c2 = ip.image.image[y][2][p2];
00521
00522 horizontal = abs(a1 - a2) + abs(b1 - b2) + abs(c1 - c2);
00523
00524 p1 = y-1;
00525 p2 = y+1;
00526 a1 = ip.image.image[p1][0][x];
00527 b1 = ip.image.image[p1][1][x];
00528 c1 = ip.image.image[p1][2][x];
00529 a2 = ip.image.image[p2][0][x];
00530 b2 = ip.image.image[p2][1][x];
00531 c2 = ip.image.image[p2][2][x];
00532
00533 vertical = abs(a1 - a2) + abs(b1 - b2) + abs(c1 - c2);
00534
00535 return (vertical > horizontal) ? vertical : horizontal;
00536 }
00537
00538 inline void addColor(){
00539 if (lastColor != -1){
00540 colorBuffer[bufferSize] = lastColor;
00541 ranges[bufferSize] = colorRange;
00542 bufferSize++;
00543 colorRange = 0;
00544 }
00545 else{
00546 colorRange = 0;
00547 }
00548 }
00549
00550
00551
00552
00553
00554 inline bool insideImage(int x,int y){
00555 if (x < 1 || x > ip.image.cameraInfo.resolutionWidth-2) return false;
00556 if (y < 1 || y > ip.image.cameraInfo.resolutionHeight-2) return false;
00557 return true;
00558 }
00559
00560
00561
00562
00563
00564 inline int susanVote(int x,int y){
00565 if (x < 1 || x > ip.image.cameraInfo.resolutionWidth-2) return -1;
00566 if (y < 1 || y > ip.image.cameraInfo.resolutionHeight-2) return -1;
00567 int vote = susanDetector.isEdgePoint(ip.image,x,y,SUSANEdgeDetectionLite::componentA);
00568 vote += susanDetector.isEdgePoint(ip.image,x,y,
00569 SUSANEdgeDetectionLite::componentB);
00570 vote += susanDetector.isEdgePoint(ip.image,x,y,
00571 SUSANEdgeDetectionLite::componentC);
00572 return vote;
00573 }
00574
00575
00576
00577 };
00578
00579 #endif// __REdgeDetection_h_
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