Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

Modules/ImageProcessor/ImageProcessorTools/GT2004EdgeDetection.h

Go to the documentation of this file.
00001 /**
00002 * @file Modules/ImageProcessor/ImageProcessorTools/GT2004EdgeDetection.h
00003 * 
00004 * This file contains an utility-class for detecting edges in digital images. 
00005 *
00006 * @author <A href="mailto:sadprofessor@web.de">Bernd Schmidt</A>
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 * @class GT2004EdgeDetection
00019 * Utility-class for edge-detection.
00020 */
00021 class GT2004EdgeDetection
00022 {  
00023 
00024 public:
00025 
00026   /**
00027   * Default constructor.
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   /** Follows the given direction,
00053     and determines edges by the sum of all three channels.
00054     The position of the edge is stored in x and y.
00055     @param x The starting x-value.
00056     @param y The starting y-value.
00057         @param direction The direction followed.
00058     @return edge was found*/
00059   bool scan(int& x,int& y,Vector2<double> direction);
00060 
00061   /** Follows the given direction,
00062     and determines edges by the sum of all three channels.
00063     The position of the edge is stored in x and y.
00064     Fills the colorBuffer while scanning, so the client
00065     can determine with the colorBuffer-Array what kind of
00066     object was found.
00067 
00068     @param x The starting x-value.
00069     @param y The starting y-value.
00070         @param direction The direction followed.
00071     @return edge was found*/
00072   bool bufferedScan(int& x,int& y,Vector2<double> direction);
00073 
00074   /** Follows the last given direction. Skips 3 pixels at the beginning
00075   of each scan, while filling the buffer.*/ 
00076   bool bufferedScan(int& x,int& y);
00077 
00078     /** Follows the given direction,and searches for field-edge-points. 
00079     Determines edges by the sum of the first two channels.
00080     The position of the edge is stored in x and y.
00081     @param x The starting x-value.
00082     @param y The starting y-value.
00083         @param direction The direction followed.
00084     @return edge was found*/
00085   bool scanField(int& x,int& y,Vector2<double> direction);
00086 
00087   /** Follows the last given direction,and searches for field-edge-points. 
00088     Determines edges by the sum of the first two channels.
00089     The position of the edge is stored in x and y.
00090     @param x The starting x-value.
00091     @param y The starting y-value.
00092     @return edge was found*/
00093   bool scanField(int& x,int& y);
00094 
00095   /** Follows the last given direction,
00096     and determines edges by the sum of all three channels */
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     //could be different code as in crossEdgeVote()
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   /* implemented with colorCorrection*/
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     //TODO remove hack for color correction
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   /** Gives the next pixel of last scan. This is only for the scans that
00271     use Bresenham's algorithm.*/
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 //Bresenham
00314 /*inline void draw_line(int x0, int y0, int x1, int y1){
00315   int x,y=y0,dx = 2*(x1-x0),dy = 2*(y1-y0);
00316   int dydx = dy - dx, d = dy - dx/2;
00317   for(x=x0;x<=x1;x++){
00318     DOT(imageProcessor_general,x,y,
00319       Drawings::white, Drawings::red);
00320     if(d<0) {d+= dy;}
00321     else {y+=1; d += dydx;}
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   /** This buffer is used to store the colors 
00360   * passed by a buffered scan-method during the last scan
00361   */
00362   colorClass colorBuffer[20];
00363 
00364   /** This buffer is used to store the ranges of the colors */
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     //~ if (susanDetector.isEdgePoint(ip.image,x,y,
00418       //~ SUSANEdgeDetectionLite::componentA)) ++i;
00419     if (susanDetector.isEdgePoint(ip.image,x,y,
00420       SUSANEdgeDetectionLite::componentB)) ++i;
00421     //if (susanDetector.isEdgePoint(ip.image,x,y,
00422     //  SUSANEdgeDetectionLite::componentC)) ++i;
00423     return i;
00424   }
00425 
00426 
00427   
00428 };
00429 
00430 #endif// __GT2004EdgeDetection_h_

Generated on Mon Mar 20 21:59:50 2006 for GT2005 by doxygen 1.3.6