00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef __GT2004EdgeDetection_h_
00010 #define __GT2004EdgeDetection_h_
00011
00012 #include "Representations/Perception/Image.h"
00013 #include "Modules/ImageProcessor/ImageProcessor.h"
00014 #include "Modules/ImageProcessor/ImageProcessorTools/MSH2004ColorCorrector.h"
00015 #include "Modules/ImageProcessor/ImageProcessorTools/SUSANEdgeDetectionLite.h"
00016
00017
00018
00019
00020
00021 class GT2004EdgeDetection
00022 {
00023
00024 public:
00025
00026
00027
00028
00029
00030 GT2004EdgeDetection(ImageProcessor& processor,MSH2004ColorCorrector& corrector);
00031
00032 ~GT2004EdgeDetection();
00033
00034 int threshold;
00035
00036 int tempX;
00037
00038 int tempY;
00039
00040 bool scanEast(int& x, int& y);
00041
00042 bool scanWest(int& x, int& y);
00043
00044 bool scanNorth(int& x, int& y);
00045
00046 bool scanSouth(int& x, int& y);
00047
00048 bool ballScanEast(int& x, int& y);
00049
00050 bool ballScanWest(int& x, int& y);
00051
00052
00053
00054
00055
00056
00057
00058
00059 bool scan(int& x,int& y,Vector2<double> direction);
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 bool bufferedScan(int& x,int& y,Vector2<double> direction);
00073
00074
00075
00076 bool bufferedScan(int& x,int& y);
00077
00078
00079
00080
00081
00082
00083
00084
00085 bool scanField(int& x,int& y,Vector2<double> direction);
00086
00087
00088
00089
00090
00091
00092
00093 bool scanField(int& x,int& y);
00094
00095
00096
00097 bool scan(int& x,int& y);
00098
00099 bool colorScan(int& x,int& y,Vector2<double> direction,colorClass& lastColor);
00100
00101 bool colorScan(int& x,int& y,colorClass& lastColor);
00102
00103 bool susanScan(int& x,int& y,Vector2<double> direction);
00104
00105 bool scan(int& x,int& y,int x1,int y1);
00106
00107 bool colorScan(int& x,int& y,int x1,int y1,colorClass& lastColor);
00108
00109 inline void setDirection(Vector2<double> dir){
00110 cx = (dir.x<0)? -1 : 1;
00111 cy = (dir.y<0)? -1 : 1;
00112 dx = abs((int)(dir.x * 500.0f));
00113 dy = abs((int)(dir.y * 500.0f));
00114 if (dx>dy){
00115 e = dx - 2*dy;
00116 f = 2*(dx - dy);
00117 g = -2*dy;
00118 }
00119 else{
00120 e = dy - 2*dx;
00121 f = 2*(dy - dx);
00122 g = -2*dx;
00123 }
00124 direction = dir;
00125 }
00126
00127 inline colorClass getColor(int index){
00128 return colorBuffer[index];
00129 }
00130
00131 inline int getRange(int index){
00132 return ranges[index];
00133 }
00134
00135 inline bool isHorizontalEdge(int x, int y){
00136 return horizontalEdgeVote(x,y) > threshold;
00137 }
00138
00139 inline int horizontalEdgeVote(int x,int y){
00140 if (x < 1 || x > ip.image.cameraInfo.resolutionWidth-2) return -1;
00141 int cx1 = x-1;
00142 int cx2 = x+1;
00143 int a1 = ip.image.image[y][0][cx1];
00144 int b1 = ip.image.image[y][1][cx1];
00145 int c1 = ip.image.image[y][2][cx1];
00146 int a2 = ip.image.image[y][0][cx2];
00147 int b2 = ip.image.image[y][1][cx2];
00148 int c2 = ip.image.image[y][2][cx2];
00149
00150 return abs(a1 - a2) + abs(b1 - b2) + abs(c1 - c2);
00151 }
00152
00153 inline bool isVerticalEdge(int x, int y){
00154 return verticalEdgeVote(x,y) > threshold;
00155 }
00156
00157 inline int verticalEdgeVote(int x,int y){
00158 if (y < 1 || y > ip.image.cameraInfo.resolutionHeight-2) return -1;
00159 int cy1 = y-1;
00160 int cy2 = y+1;
00161 int a1 = ip.image.image[cy1][0][x];
00162 int b1 = ip.image.image[cy1][1][x];
00163 int c1 = ip.image.image[cy1][2][x];
00164 int a2 = ip.image.image[cy2][0][x];
00165 int b2 = ip.image.image[cy2][1][x];
00166 int c2 = ip.image.image[cy2][2][x];
00167
00168 return abs(a1 - a2) + abs(b1 - b2) + abs(c1 - c2);
00169 }
00170
00171 inline int ballEdgeVote(int x,int y){
00172
00173 if (x < 1 || x > ip.image.cameraInfo.resolutionWidth-2) return -1;
00174 if (y < 1 || y > ip.image.cameraInfo.resolutionHeight-2) return -1;
00175 int vertical = 0;
00176 int horizontal = 0;
00177 int p1 = x-1;
00178 int p2 = x+1;
00179 int a1 = ip.image.image[y][0][p1];
00180 int b1 = ip.image.image[y][1][p1];
00181 int c1 = ip.image.image[y][2][p1];
00182 int a2 = ip.image.image[y][0][p2];
00183 int b2 = ip.image.image[y][1][p2];
00184 int c2 = ip.image.image[y][2][p2];
00185
00186 horizontal = abs(a1 - a2) + abs(b1 - b2) + abs(c1 - c2);
00187
00188 p1 = y-1;
00189 p2 = y+1;
00190 a1 = ip.image.image[p1][0][x];
00191 b1 = ip.image.image[p1][1][x];
00192 c1 = ip.image.image[p1][2][x];
00193 a2 = ip.image.image[p2][0][x];
00194 b2 = ip.image.image[p2][1][x];
00195 c2 = ip.image.image[p2][2][x];
00196
00197 vertical = abs(a1 - a2) + abs(b1 - b2) + abs(c1 - c2);
00198
00199 return (vertical > horizontal) ? vertical : horizontal;
00200 }
00201
00202 inline int crossEdgeVote(int x,int y){
00203 if (x < 1 || x > ip.image.cameraInfo.resolutionWidth-2) return -1;
00204 if (y < 1 || y > ip.image.cameraInfo.resolutionHeight-2) return -1;
00205 int vertical = 0;
00206 int horizontal = 0;
00207 int p1 = x-1;
00208 int p2 = x+1;
00209 int a1 = ip.image.image[y][0][p1];
00210 int b1 = ip.image.image[y][1][p1];
00211 int c1 = ip.image.image[y][2][p1];
00212 int a2 = ip.image.image[y][0][p2];
00213 int b2 = ip.image.image[y][1][p2];
00214 int c2 = ip.image.image[y][2][p2];
00215
00216 horizontal = abs(a1 - a2) + abs(b1 - b2) + abs(c1 - c2);
00217
00218 p1 = y-1;
00219 p2 = y+1;
00220 a1 = ip.image.image[p1][0][x];
00221 b1 = ip.image.image[p1][1][x];
00222 c1 = ip.image.image[p1][2][x];
00223 a2 = ip.image.image[p2][0][x];
00224 b2 = ip.image.image[p2][1][x];
00225 c2 = ip.image.image[p2][2][x];
00226
00227 vertical = abs(a1 - a2) + abs(b1 - b2) + abs(c1 - c2);
00228
00229 return (vertical > horizontal) ? vertical : horizontal;
00230 }
00231 inline int fieldEdgeVote(int x,int y){
00232 if (x < 1 || x > ip.image.cameraInfo.resolutionWidth-2) return -1;
00233 if (y < 1 || y > ip.image.cameraInfo.resolutionHeight-2) return -1;
00234 int vertical = 0;
00235 int horizontal = 0;
00236 int p1 = x-1;
00237 int p2 = x+1;
00238 int a1 = ip.image.image[y][0][p1];
00239 int b1 = ip.image.image[y][1][p1];
00240 int a2 = ip.image.image[y][0][p2];
00241 int b2 = ip.image.image[y][1][p2];
00242
00243
00244 horizontal = abs(a1 - a2) + abs(b1 - b2);
00245
00246 p1 = y-1;
00247 p2 = y+1;
00248 a1 = ip.image.image[p1][0][x];
00249 b1 = ip.image.image[p1][1][x];
00250 a2 = ip.image.image[p2][0][x];
00251 b2 = ip.image.image[p2][1][x];
00252
00253 vertical = abs(a1 - a2) + abs(b1 - b2);
00254
00255 return (vertical > horizontal) ? vertical : horizontal;
00256 }
00257
00258 inline colorClass getColor(int x,int y){
00259 if (x < 1 || x > ip.image.cameraInfo.resolutionWidth-2) return (colorClass)-1;
00260 if (y < 1 || y > ip.image.cameraInfo.resolutionHeight-2) return (colorClass)-1;
00261
00262
00263 unsigned char cy = ip.image.image[y][0][x];
00264 unsigned char cu = ip.image.image[y][1][x];
00265 unsigned char cv = ip.image.image[y][2][x];
00266 corrector.getCorrectedPixel(x,y,cy,cu,cv);
00267 return ip.colorTable.getColorClass(cy,cu,cv);
00268 }
00269
00270
00271
00272 inline void skip(int& x,int& y){
00273 if (dx>dy){
00274 x+=cx;
00275 if (e<0) {
00276 y+=cy;
00277 e+=f;
00278 }
00279 else {
00280 e+=g;
00281 }
00282 }
00283 else{
00284 y+=cy;
00285 if (e<0) {
00286 x+=cx;
00287 e+=f;
00288 }
00289 else {
00290 e+=g;
00291 }
00292 }
00293 }
00294
00295 inline bool findStart(Vector2<int>& start,const Vector2<double>& dir){
00296 int dx = (int)(dir.x*300 + 0.5);
00297 int dy = (int)(dir.y*300 + 0.5);
00298
00299 Vector2<int> rightBorder(start.x + dx,start.y + dy);
00300
00301 return Geometry::clipLineWithRectangleCohenSutherland(
00302 Vector2<int>(1,1),
00303 Vector2<int>(ip.image.cameraInfo.resolutionWidth -2,ip.image.cameraInfo.resolutionHeight -2),
00304 start,
00305 rightBorder
00306 );
00307 }
00308
00309 inline int getBufferSize(){
00310 return bufferSize;
00311 }
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 private:
00328
00329 ImageProcessor& ip;
00330
00331 SUSANEdgeDetectionLite susanDetector;
00332
00333 MSH2004ColorCorrector corrector;
00334
00335 Vector2<double> direction;
00336
00337 int e;
00338
00339 int f;
00340
00341 int g;
00342
00343 int dx;
00344
00345 int dy;
00346
00347 int cx;
00348
00349 int cy;
00350
00351 int bufferSize;
00352
00353 colorClass currentColor;
00354
00355 colorClass lastColor;
00356
00357 int colorRange;
00358
00359
00360
00361
00362 colorClass colorBuffer[20];
00363
00364
00365 int ranges[20];
00366
00367 inline int fastCrossEdgeVote(int x,int y){
00368 int vertical = 0;
00369 int horizontal = 0;
00370 int p1 = x-1;
00371 int p2 = x+1;
00372 int a1 = ip.image.image[y][0][p1];
00373 int b1 = ip.image.image[y][1][p1];
00374 int c1 = ip.image.image[y][2][p1];
00375 int a2 = ip.image.image[y][0][p2];
00376 int b2 = ip.image.image[y][1][p2];
00377 int c2 = ip.image.image[y][2][p2];
00378
00379 horizontal = abs(a1 - a2) + abs(b1 - b2) + abs(c1 - c2);
00380
00381 p1 = y-1;
00382 p2 = y+1;
00383 a1 = ip.image.image[p1][0][x];
00384 b1 = ip.image.image[p1][1][x];
00385 c1 = ip.image.image[p1][2][x];
00386 a2 = ip.image.image[p2][0][x];
00387 b2 = ip.image.image[p2][1][x];
00388 c2 = ip.image.image[p2][2][x];
00389
00390 vertical = abs(a1 - a2) + abs(b1 - b2) + abs(c1 - c2);
00391
00392 return (vertical > horizontal) ? vertical : horizontal;
00393 }
00394
00395 inline void addColor(){
00396 if (lastColor != -1){
00397 colorBuffer[bufferSize] = lastColor;
00398 ranges[bufferSize] = colorRange;
00399 bufferSize++;
00400 colorRange = 0;
00401 }
00402 else{
00403 colorRange = 0;
00404 }
00405 }
00406
00407 inline bool insideImage(int x,int y){
00408 if (x < 1 || x > ip.image.cameraInfo.resolutionWidth-2) return false;
00409 if (y < 1 || y > ip.image.cameraInfo.resolutionHeight-2) return false;
00410 return true;
00411 }
00412
00413 inline int susanVote(int x,int y){
00414 if (x < 1 || x > ip.image.cameraInfo.resolutionWidth-2) return -1;
00415 if (y < 1 || y > ip.image.cameraInfo.resolutionHeight-2) return -1;
00416 int i = 0;
00417
00418
00419 if (susanDetector.isEdgePoint(ip.image,x,y,
00420 SUSANEdgeDetectionLite::componentB)) ++i;
00421
00422
00423 return i;
00424 }
00425
00426
00427
00428 };
00429
00430 #endif// __GT2004EdgeDetection_h_