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