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

Modules/ImageProcessor/VLCImageProcessor/VLCGoalRecognizer.h

Go to the documentation of this file.
00001 /**
00002 * @file VLCGoalRecognizer.h
00003 *
00004 * @author <a href="mailto:oberlies@sim.tu-darmstadt.de">Tobias Oberlies</a>
00005 */
00006 
00007 #ifndef VLCGoalRecognizer_h_
00008 #define VLCGoalRecognizer_h_
00009 
00010 #include "Modules/ImageProcessor/ImageProcessor.h"
00011 #include "Modules/ImageProcessor/ImageProcessorTools/ImageProcessorUtilityClasses.h"
00012 #include "Modules/ImageProcessor/ImageProcessorTools/BresenhamLineScan.h"
00013 #include "Modules/ImageProcessor/ImageProcessorTools/ColorCorrector.h"
00014 
00015 
00016 /**
00017  * Macro to handle the stupid problem, that the DEBUG_IMAGE_SET_PIXEL_xxx macros need the 
00018  * debug image identifier at compile time. There are two instances of this class, and one of 
00019  * them uses imageProcessorGoal1 and the other imageProcessorGoal2.
00020  * @param targetcolor A variable that contains the goal colour at runtime.
00021  * @param x The x-value of the pixel to be set (at runtime).
00022  * @param y The y-value of the pixel to be set (at runtime).
00023  * @param drawcolor Text suitable to complete DEBUG_IMAGE_SET_PIXEL_ at compile time.
00024  */
00025 #ifndef NDEBUG
00026 #define STUPID_DEBUG_IMAGE_SET_PIXEL(targetcolor, x, y, drawcolor) \
00027   if (targetcolor == yellow) \
00028   { \
00029     DEBUG_IMAGE_SET_PIXEL_##drawcolor(imageProcessorGoal1, (x), (y)); \
00030   } \
00031   else \
00032   { \
00033     DEBUG_IMAGE_SET_PIXEL_##drawcolor(imageProcessorGoal2, (x), (y)); \
00034   }
00035 
00036 #define N_STUPID_DEBUG_IMAGE_SET_PIXEL(targetcolor, x, y, drawcolor) \
00037   if (targetcolor == yellow) \
00038   { \
00039     N_SET_COLORED_PIXEL_IN_GRAY_SCALE_IMAGE(goalRecognizerYellow, (x), (y), (drawcolor)); \
00040   } \
00041   else \
00042   { \
00043     N_SET_COLORED_PIXEL_IN_GRAY_SCALE_IMAGE(goalRecognizerBlue, (x), (y), (drawcolor)); \
00044   }
00045 
00046 #else
00047 
00048 #define STUPID_DEBUG_IMAGE_SET_PIXEL(targetcolor, x, y, drawcolor) ;
00049 #define N_STUPID_DEBUG_IMAGE_SET_PIXEL(targetcolor, x, y, drawcolor) ;
00050 
00051 #endif
00052 
00053 /**
00054  * @class VLCGoalRecognizer
00055  *
00056  * TODO: Write Summary
00057  * 
00058  * @author <a href="mailto:oberlies@sim.tu-darmstadt.de"Tobias Oberlies</a>
00059  */ 
00060 class VLCGoalRecognizer
00061 {
00062 private: // nested classes and enums
00063 
00064   /**
00065    * TODO: Write Summary
00066    */
00067   enum EdgeType
00068   {
00069     none = 0,
00070     edge,
00071     deviationWithoutEdge,
00072     imageBorder       // Must be the last one
00073   };
00074 
00075   /**
00076    * TODO: Write Summary
00077    */
00078   class EdgeDetector
00079   {
00080   public:
00081     /** Constructor. */
00082     EdgeDetector(colorClass target);
00083     EdgeDetector(colorClass target, Vector3<int> referenceColor, int referenceColorBase);
00084 
00085     /**
00086      * Investigates the next pixel and reports, wether an edge, or repeated deviation of 
00087      * the pixel colours (without the indications of an edge) have been detected. It is 
00088      * assumed that edges are quite sharp and that the color beyond the edge is 
00089      * significantly different to the goal colour. In case of a blurred edge or a steady
00090      * color gradient the method will (eventually) return deviationWithoutEdge.
00091      */
00092     inline EdgeType inspectPixel(const Vector2<int>& point, int index, const colorClass& colorCls, const Vector3<int>& color)
00093     {
00094       // Check, if pixel is in target colour class
00095       if (colorCls == targetColorClass)
00096       {
00097         // Store as possible edge point
00098         lastPointInClass = point;
00099         lastPointInClassIndex = index;
00100         connectedToClass = true;
00101 
00102         // Update the reference colour
00103         // The reference colour is an average of the colour of the last pixels. If
00104         // this method has been called on less than eight pixels, the average is 
00105         // equally weighted. Otherwise recent pixels have a higher weight (1/8 for 
00106         // the last one etc.)
00107         referenceColor = (referenceColor * referenceColorBase + color) / (referenceColorBase+1);
00108         if (referenceColorBase < 7)
00109           ++referenceColorBase;
00110 
00111         // Decrease deviation counter (since this pixel has no deviation)
00112         deviationCounter = deviationCounter<=4 ? 0 : deviationCounter-4;
00113 
00114         // Reset edge counter (assuming no pixels in the goal color class beyond the edge)
00115         edgeCounter = 0;
00116       }
00117       else if (colorCls != noColor && colorCls != ignoredClassification)
00118       {
00119         // Pixel is classified as a different colour. Take this as an indication for
00120         // an edge.
00121         ++edgeCounter;
00122         deviationCounter = deviationCounter + 2;
00123 
00124         // From now on don't use pixels with tolerable (but non-zero) pixels as 
00125         // lastPointInClass, because they're likely to be noise
00126         connectedToClass = false;
00127     
00128         // Check whether an edge or excessive deviation have been detected
00129         if (edgeCounter >= 3)
00130           return edge;
00131         else if (deviationCounter >= 10)
00132           return deviationWithoutEdge;
00133 
00134       }
00135       else
00136       {
00137         // Pixel is not classified in any color class, so calculate the distance to 
00138         // the reference color for further investigations
00139         int dist = distance(color);
00140 
00141         // Update deviation and edge counters
00142         if (dist < classThreshold)
00143         {
00144           // This pixel very likely to be part of the goal.
00145           if (edgeCounter > 0)
00146             --edgeCounter;
00147           ++deviationCounter;
00148 
00149           // Store as possible edge point if there haven't been any (strong) 
00150           // indications for an edge since the last pixel in the target class
00151           if (connectedToClass)
00152           {
00153             lastPointInClass = point;
00154             lastPointInClassIndex = index;
00155           }
00156         }
00157         else if(dist < edgeThreshold)
00158         {
00159           // This pixel is neither likely to be part of the goal, nor to be bejond
00160           // the edge. Since we're looking for a reasonably sharp edge, only few
00161           // pixels in this distance range are expected to occur.
00162           deviationCounter = deviationCounter + 2;
00163           connectedToClass = false;
00164         }
00165         else
00166         {
00167           // This pixel is likely to be beyond the edge of the goal. In this case
00168           // the edge counter is increased more than the deviation counter (with 
00169           // respect to their trigger thresholds 3 and 10). Hence in case of a 
00170           // clear edge, the edge will trigger before the deviation.
00171           ++edgeCounter;
00172           deviationCounter = deviationCounter + 2;
00173           connectedToClass = false;
00174         }
00175 
00176         // Check whether an edge or excessive deviation have been detected
00177         if (edgeCounter >= 3)
00178           return edge;
00179         else if (deviationCounter >= 10)
00180           return deviationWithoutEdge;
00181       }
00182 
00183       return none;
00184     }
00185 
00186     /**
00187      * Returns the last point in the target colour class. If inspectPixel return the 
00188      * value edge the returned point is located just before the edge. 
00189      */
00190     inline Vector2<int> getLastPointInClass()
00191     {
00192       return lastPointInClass;
00193     };
00194 
00195     /**
00196      * Similar to getLastPointInClass().
00197      */
00198     inline void getLastPointInClass(Vector2<int>& point)
00199     {
00200       point = lastPointInClass;
00201     }
00202 
00203     /**
00204      * Similar to getLastPointInClass(), but also returns the index of the 
00205      * lastPointInClass.
00206      */
00207     inline void getLastPointInClass(Vector2<int>& point, int& index)
00208     {
00209       point = lastPointInClass;
00210       index = lastPointInClassIndex;
00211     }
00212 
00213     /**
00214      * Similar to getLastPointInClass(), but returns the index of the lastPointInClass
00215      * instead of the poinst itself.
00216      */
00217     inline int getLastIndexInClass()
00218     {
00219       return lastPointInClassIndex;
00220     }
00221 
00222     /**
00223      * Resets the edge detection state while keeping the reference colour.
00224      * @param defaultLast The value returned by getLastPointInClass if none of the
00225      * inspected pixels is in or near the target colour class.
00226      * @param connectedToClass Assume that the first pixel that is inspected is 
00227      * connected to the target colour class.
00228      */
00229     void clear(const Vector2<int>& defaultLast, bool connectedToClass)
00230     {
00231       // Reset the counters
00232       deviationCounter = 0;
00233       edgeCounter = 0;
00234 
00235       // Set provided default values
00236       this->lastPointInClass = defaultLast;
00237       this->lastPointInClassIndex = -1;
00238       this->connectedToClass = connectedToClass;
00239     }
00240 
00241     /**
00242      * Reset the edge detection state while keeping the reference colour.
00243      */
00244     void clear()
00245     {
00246       // Reset the counters
00247       deviationCounter = 0;
00248       edgeCounter = 0;
00249 
00250       // Keep the lastPointInClass value assuming that the scan begins there (hence
00251       // first pixel inspected is connected to the class)
00252       lastPointInClassIndex = -1;
00253       connectedToClass = true;
00254     }
00255 
00256     /**
00257      * Reset the reference colour and the edge detector state.
00258      */
00259     void reset()
00260     {
00261       // Reset the reference colour
00262       referenceColorBase = 0;
00263 
00264       // Reset the counters
00265       deviationCounter = 0;
00266       edgeCounter = 0;
00267 
00268       // Keep the lastPointInClass value assuming that the scan begins there (hence
00269       // first pixel inspected is connected to the class)
00270       lastPointInClassIndex = -1;
00271       connectedToClass = false;
00272     }
00273 
00274     /**
00275      * Sets the reference colour.
00276      */
00277     void setReferenceColor(const Vector3<int>& color, int referenceColorBase)
00278     {
00279       this->referenceColor = color;
00280       this->referenceColorBase = referenceColorBase;
00281     };
00282 
00283     /**
00284      * Returns the reference colour.
00285      */
00286     void getReferenceColor(Vector3<int>& result)
00287     {
00288       result = this->referenceColor;
00289     };
00290 
00291   private: // methods
00292 
00293     /**
00294      * Calculates the Mahalanobis distance of the given colour to the reference colour.
00295      */
00296     inline int distance(const Vector3<int>& color)
00297     {
00298       // Calculate difference in each channel
00299       Vector3<int> difference = color - referenceColor;
00300 
00301       // Weigh with respect to usual variation
00302       return (invCovar * difference) * difference;  // in MATLAB syntax: difference'*invCovar*difference
00303     }
00304 
00305   private: // class members
00306 
00307     /** The maximum distance from the reference colour that is tolerated for a pixel to
00308       be considered in the target colour class. */
00309     static const float classThreshold;
00310 
00311     /** The minimum distance from the reference colour that pixels on the other side of
00312       an edge need to have. This value is greater than classThreshold. */
00313     static const float edgeThreshold;
00314 
00315 
00316   private: // members
00317 
00318     /** The colour class of the goal. */
00319     const colorClass targetColorClass;
00320 
00321     /** Colour class that is not considered as an indication for an edge. */
00322     const colorClass ignoredClassification;
00323 
00324     /** The inverse covariance matrix of the goal colour. It is used to calculate the
00325         Mahalanobis distance between the reference colour and the current colour for 
00326       pixels in no colour class (or an ignored one). */
00327     const Matrix3x3<int> invCovar;
00328 
00329     /** The reference colour for distance calculations. It is an average of recent 
00330         pixels that were classified in the target colour class. */
00331     Vector3<int> referenceColor;
00332     int referenceColorBase;
00333 
00334     /** Counter to detect the end of an area in target colour without an edge. */
00335     int deviationCounter;
00336 
00337     /** Counter to detect an edge. */
00338     int edgeCounter;
00339 
00340 
00341     /** Last pixel in the target colour class (or within tolerable distance). */
00342     Vector2<int> lastPointInClass;
00343 
00344     /** The index of the last point in/near the target colour class. By default, this
00345       value is -1, so it can be used to check whether any pixel was considered to be
00346       in/near the target colour class. */
00347     int lastPointInClassIndex;
00348 
00349     /** Current pixel is connected via to a pixel in the target colour class only via 
00350         pixels within tolerable distance, i.e. there hasn't been a pixel with a distance
00351       greater than the classDistance threshold since the last pixel classified in the
00352       target class (without distance). As long as this variable is true, points with
00353       tolerable distance will be stored as lastPointInClass. */
00354     bool connectedToClass;
00355     
00356   }; // class VLCGoalRecognizer::EdgeDetector
00357 
00358   
00359   /**
00360    * TODO: Write Summary
00361    */
00362   struct EdgePointList
00363   {
00364   private: // members
00365     
00366     // Arrays to store the edge points and their type
00367     enum {maxPoints = 20};
00368     Vector2<int> edgePoint[maxPoints];
00369     VLCGoalRecognizer::EdgeType edgeType[maxPoints];
00370 
00371     // Current number of edge points
00372     int numberOfPoints;
00373 
00374     // Number of edge points of a certain type
00375     int numberOfType[imageBorder+1];
00376 
00377 
00378   public: // methods
00379 
00380     /** Constructs an empty list. */
00381     EdgePointList()
00382       : numberOfPoints(0)
00383     {
00384       for (int i=0; i<=imageBorder; ++i)
00385         numberOfType[i] = 0;
00386     }
00387 
00388     /** Add an edge point to the list. */
00389     inline void add(Vector2<int>& point, VLCGoalRecognizer::EdgeType type)
00390     {
00391       // Ignore if too many points
00392       if (numberOfPoints>=maxPoints)
00393         return;
00394 
00395       // Store point and increase counters
00396       edgePoint[numberOfPoints] = point;
00397       edgeType[numberOfPoints] = type;
00398       ++numberOfPoints;
00399       ++numberOfType[type];
00400     }
00401 
00402     /** Returns the current size of the list. */
00403     inline int size()
00404     {
00405       return numberOfPoints;
00406     }
00407 
00408     /** Returns the number of edge points of a certain type. */
00409     inline int getCount(VLCGoalRecognizer::EdgeType type)
00410     {
00411       return numberOfType[type];
00412     }
00413 
00414     /** Returns an element of the list. */
00415     inline Vector2<int>& operator[](int index)
00416     {
00417       return edgePoint[index];
00418     }
00419 
00420     /** Returns the type of an edge points. */
00421     inline VLCGoalRecognizer::EdgeType getType(int index)
00422     {
00423       return edgeType[index];
00424     }
00425   }; // struct EdgePointList
00426 
00427 
00428   /**
00429    *
00430    */
00431   struct Goalpost
00432   {
00433     /** Constructs an empty goalpost hypothesis. */
00434     Goalpost() {};
00435 
00436     /** Top endpoints of the goalposts. Might not be aligned with the edge 
00437         horizontally. */
00438     Vector2<int> topPoint;
00439     Vector2<double> topPointH;
00440     bool topPointInImage; // FILL
00441 
00442     /** Bottom endpoints of the goalpost. Might not be aligned with the edge 
00443         horizontally. */
00444     Vector2<int> bottomPoint;
00445     Vector2<double> bottomPointH;
00446 
00447     /** Goalpost is standing on the green field. */
00448     bool onGreen;
00449 
00450     /** Height and height not conting the image border. */
00451     int height;
00452     int visibleHeight; // FILL
00453 
00454     /** A point aligned with the edge of the goalpost. */
00455     Vector2<int> edgePoint;
00456     Vector2<double> edgePointH;
00457 
00458     /** Number of strong and weak edge points detected. */
00459     int strongEdgeCount;
00460     int weakEdgeCount;
00461 
00462     /** Straightness */
00463     /** Slope */
00464 
00465     /** Scans towards the edge detected unbound goal-coloured areas. This often happens 
00466       when goals are dectected twice, or the scan along the cross bar failed. If this 
00467       value is set to true, all other values are invalid.*/
00468     bool nonExistant;
00469 
00470     /** Average colour of some pixels near the goalpost. This value is used to 
00471       detect the free part of goal (is done in the interpretation after the entire
00472       image was scanned) or straightnes checks. */
00473     Vector3<int> color;
00474 
00475   }; // struct Goalpost
00476 
00477   /**
00478    * TODO: Write Summary
00479    */
00480   struct GoalHypothesis
00481   {
00482     /** Constructs an empty GoalHypothesis with default values. */
00483     GoalHypothesis(){};
00484     
00485     /** The left and right goalpost. */
00486     Goalpost goalpost[2];
00487 
00488     /** Right end of cross bar. */
00489     Vector2<int> crossBarEndpoint;
00490     Vector2<double> crossBarEndpointH;
00491 
00492     /** Goal width. */
00493     int width;
00494 
00495     /** Goal height (the maximum of the goalpost heights). */
00496     int height;
00497 
00498     /** There is green below the goal hypthesis. */
00499     bool onGreen;
00500 
00501   }; // struct GoalHypothesis
00502 
00503 
00504   /**
00505    * TODO: Write Summary
00506    */
00507   enum ImageBorderSide
00508   {
00509     topBorder = 0,
00510     leftBorder = 1,
00511     bottomBorder = 2,
00512     rightBorder = 3,
00513     noBorder
00514   };
00515   
00516   enum FreeSide
00517   {
00518     noFreeSide,
00519     leftSide,
00520     rightSide,
00521     bothSides
00522   };
00523 
00524 
00525 // class VLCGoalRecognizer
00526 
00527 public:
00528 
00529   /**
00530    * Initializes the VLCGoadRecognizer.
00531    */
00532   VLCGoalRecognizer(colorClass color, const ImageProcessorInterfaces& interfaces, const ColorCorrector& colorCorrector, const ImageInfo& horizonInfo);
00533   
00534   /**
00535    * Destructor
00536    */
00537   ~VLCGoalRecognizer() {};
00538   
00539   /**
00540    * This method has to be called before a new image is scanned.
00541    */
00542   void notifyAboutNewImage();
00543 
00544 
00545   void notifyAboutFinish();
00546 
00547 
00548 
00549   // for VLC
00550   void setBestColorTable(ColorTable * newBestColorTable)
00551   {
00552     bestColorTable = newBestColorTable;
00553   }
00554   //
00555 
00556 
00557   inline void notifyAboutNewScanline(const Vector2<int>& scanLineStart)
00558   {
00559     // Reset counter for detection of goal candidates
00560     detectionCounter = 0;
00561 
00562     // Calculate how many pixels on this scanline should be skipped in order to prevent 
00563     // previously recognized goals to be found again
00564     calculateLockedPixels(scanLineStart);
00565   };
00566 
00567 
00568   inline void inspectPixel(const Vector2<int>& point, const colorClass& color)
00569   {
00570     // Check if this pixel is inside the area that has been analysed before
00571     if (--lockedPixels < 0)
00572     {
00573 
00574       // Check if pixel has target colour 
00575       if (color == goalColor)
00576       {
00577         // Increase counter
00578         ++detectionCounter;
00579 
00580         // When counter reaches 3, start the actual goal detection routine
00581         if (detectionCounter >= 4)
00582         {
00583           STUPID_DEBUG_IMAGE_SET_PIXEL(goalColor, point.x, point.y, BLUE);
00584 
00585           if (true)//inspectNeighbourhood(point))
00586           {
00587             // Analyze this blob
00588             analyzeGoal(point);
00589 
00590             // Recalculate the number of locked pixels on this scanline
00591             recalculateLockedPixels(point);
00592 
00593             //testDone = true;
00594             //testNow = false;
00595             detectionCounter = 0;
00596           }
00597           else
00598           {
00599             // Take into account that there were only few goal-coloured pixels in
00600             // the neighbourhood of the current pixel
00601             detectionCounter = 1;
00602           }
00603         }
00604         else
00605           STUPID_DEBUG_IMAGE_SET_PIXEL(goalColor, point.x, point.y, GRAY);      
00606       }
00607       else
00608       {
00609         // Decrease counter
00610         --detectionCounter;
00611         if (detectionCounter<0)
00612           detectionCounter = 0;
00613         STUPID_DEBUG_IMAGE_SET_PIXEL(goalColor, point.x, point.y, GRAY);
00614       }
00615     }
00616   };
00617 
00618 
00619 private: // methods
00620   
00621   /** */
00622   bool inspectNeighbourhood(const Vector2<int>& point);
00623 
00624   /** 
00625    * point copied on purpose
00626    */
00627   void analyzeGoal(Vector2<int> startPoint);
00628 
00629 
00630   /** 
00631    * direction of edge normalized!!
00632    * imageBorderScanned: to prevent that one image border is scanned again, never necessary
00633    * in correct goal case
00634    */
00635   void analyzeGoalpost(VLCGoalRecognizer::EdgeDetector* detector,
00636                        const Vector2<double>& directionOfEdge, 
00637                        bool leftGoalpost,
00638                        Vector2<int>& focus,
00639                        VLCGoalRecognizer::Goalpost& result,
00640                        bool* imageBorderScanned);
00641 
00642   /** */
00643   void scanCrossBar(VLCGoalRecognizer::EdgeDetector* detector,
00644                     Vector2<int>& focus,
00645                     VLCGoalRecognizer::GoalHypothesis& result,
00646                     bool* imageBorderScanned);
00647 
00648   /** 
00649    * scans first from focus+scanLineOffset, using detector[0]!!
00650    */
00651   VLCGoalRecognizer::EdgeType detectEdgeTwice(VLCGoalRecognizer::EdgeDetector* detector,
00652                                                  Vector2<int>& focus,
00653                                                  BresenhamLineScan& scanLine,
00654                                                  const Vector2<int>& scanLineOffset,
00655                                                  int maxScanLength,
00656                                                  EdgePointList& edgePoints);
00657 
00658 
00659   /** */
00660   VLCGoalRecognizer::EdgeType detectEdge(VLCGoalRecognizer::EdgeDetector& detector, 
00661                                             Vector2<int>& focus, 
00662                                             BresenhamLineScan& direction,
00663                                             int maxScanLength,
00664                                             int& pixelsUntilEdge);
00665   
00666   /** */
00667   VLCGoalRecognizer::EdgeType scanAlongLine(VLCGoalRecognizer::EdgeDetector* detector,
00668                                                Vector2<int>& focus,
00669                                                BresenhamLineScan& scanLine,
00670                                                const Vector2<int>& scanLineOffset,
00671                                                int maximumScan,
00672                                                int& pixelsScanned);
00673 
00674   /** 
00675    * case noBorder mustn't be ignored -> scanning hasn't been done before or doesn't make sense 
00676    */
00677   VLCGoalRecognizer::ImageBorderSide scanOnImageBorder(VLCGoalRecognizer::EdgeDetector* detector,
00678                                                           Vector2<int>& focus,
00679                                                           const Vector2<double>& targetDirection,
00680                                                           int maxBorderDistance,
00681                                                           bool* scannedSides);
00682 
00683   /** 
00684    * direction of edge normalized!!
00685    * bottomPoint copied on purpose!!
00686    */
00687   bool detectGreenBelowGoalpost(Vector2<int> bottomPoint, 
00688                                 const Vector2<double>& directionOfEdge, 
00689                                 int goalpostHeight);
00690 
00691   /**
00692    * Returns true if the point is within one pixel distance to the image border.
00693    */
00694   inline bool nearImageBorder(const Vector2<int>& point, int maxDistance)
00695   {
00696     return point.x <= maxDistance || 
00697            point.y <= maxDistance || 
00698            point.x >= horizonInfo.maxImageCoordinates.x-maxDistance || 
00699            point.y >= horizonInfo.maxImageCoordinates.y-maxDistance;
00700   }
00701 
00702   /** */
00703   void mergeFragments(bool* deletedHypothesises);
00704 
00705 
00706   /** */
00707   void interpretResults(VLCGoalRecognizer::EdgeDetector* detector, bool* deletedHypothesises);
00708 
00709   
00710   /** */
00711   VLCGoalRecognizer::FreeSide detectFreePartOfGoal(VLCGoalRecognizer::EdgeDetector* detector, 
00712                                                       const VLCGoalRecognizer::GoalHypothesis& goal, 
00713                                                       int goalHeight, 
00714                                                       int& freeWidth, 
00715                                                       Vector2<int>& otherSide);
00716 
00717   /** */
00718   void lockArea(double x, double y, bool onGreen);
00719 
00720   /** */
00721   void calculateLockedPixels(const Vector2<int>& scanLineStart);
00722   void recalculateLockedPixels(const Vector2<int>& currentPoint);
00723 
00724 
00725 private: // members
00726 
00727   /** The colour class of the goal to be detected by this object. */
00728   const colorClass goalColor;
00729 
00730   /** Collection of references to objects that are needed by this object, e.g. the current 
00731       image, objects used to store the processing results, etc. */
00732   const ImageProcessorInterfaces& interfaces;
00733 
00734   /** Object containing useful information related to the current horizon. */
00735   const ImageInfo& horizonInfo;
00736 
00737   /** Reference to the color correction object. */
00738   const ColorCorrector& colorCorrector;
00739 
00740 
00741   /** Counter to detect accumulations of goal-coloured pixels. Used by the method 
00742       inspectPixel. */ 
00743   int detectionCounter;
00744 
00745   /** Number of pixels that will not be inspected, because they are inside previously 
00746       analysed areas. */
00747   int lockedPixels;
00748 
00749   /** Stack containing the locked area. This is to prevent that goal-coloured blobs are 
00750       analysed twice. With inspectPixel being called on pixel from left to right and top
00751       to bottom, it is sufficient to store the bottom left point of the locked areas. */
00752   enum {lockAreaStackSize = 2};
00753   Vector2<double> lockAreaStack[lockAreaStackSize];
00754   int lockAreaCount;
00755 
00756 
00757   /** Detected goal hypothesises. */
00758   enum {maxHypothesises = 5};
00759   GoalHypothesis hypothesis[maxHypothesises];
00760   int hypothesisCount;
00761 
00762   /** Declare raster image which will take debug information.
00763       NB: due to the f**king macros, I have to declare both images, even though only need 
00764       one per instance. */
00765   DECLARE_DEBUG_IMAGE(imageProcessorGoal1);
00766   DECLARE_DEBUG_IMAGE(imageProcessorGoal2);
00767 
00768   
00769   
00770   // for VLC
00771   ColorTable * bestColorTable;
00772   //
00773 
00774 };
00775 #endif // VLCGoalRecognizer

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