Bladeren bron

Merge branch 'master' of https://git.tk.informatik.tu-darmstadt.de/etri-smartspaces

Alexander Hendrich 10 jaren geleden
bovenliggende
commit
dadd844498

+ 80 - 0
bbiwarg/BBWIWARG.cs

@@ -15,24 +15,79 @@ using bbiwarg.TUIO;
 
 namespace bbiwarg
 {
+    /// <summary>
+    /// Main class which creates and starts the input, tuio and window objects.
+    /// </summary>
     class BBIWARG
     {
+        /// <summary>
+        /// the input provider
+        /// </summary>
         private InputProvider inputProvider;
+
+        /// <summary>
+        /// the input handler
+        /// </summary>
         private InputHandler inputHandler;
 
+
+        /// <summary>
+        /// true iff the tuio server is enabled
+        /// </summary>
         private bool tuioEnabled;
+
+        /// <summary>
+        /// the ip address for the tuio server
+        /// </summary>
         private String tuioIP;
+
+        /// <summary>
+        /// the port for the tuio server
+        /// </summary>
         private Int16 tuioPort;
+
+        /// <summary>
+        /// the tuio communicator
+        /// </summary>
         private TuioCommunicator tuioCommunicator;
 
+
+        /// <summary>
+        /// true iff the debug window is enabled
+        /// </summary>
         private bool debugWindowEnabled;
+
+        /// <summary>
+        /// the debug window
+        /// </summary>
         private DebugWindow debugWindow;
+
+        /// <summary>
+        /// the thread the debug window runs in
+        /// </summary>
         private Thread debugWindowThread;
 
+
+        /// <summary>
+        /// true iff the glasses window is enabled
+        /// </summary>
         private bool glassesWindowEnabled;
+
+        /// <summary>
+        /// the thread the glasses window runs in
+        /// </summary>
         private Thread glassesWindowThread;
+
+        /// <summary>
+        /// the glasses window
+        /// </summary>
         private GlassesWindow glassesWindow;
 
+
+        /// <summary>
+        /// Starts the program.
+        /// </summary>
+        /// <param name="args"></param>
         static void Main(string[] args)
         {
             Console.SetWindowSize(Parameters.ConsoleWidth, Parameters.ConsoleHeight);
@@ -41,6 +96,10 @@ namespace bbiwarg
             program.run();
         }
 
+        /// <summary>
+        /// Parses the command line arguments and depending on them creates the input, tuio and window objects.
+        /// </summary>
+        /// <param name="args">command line arguments</param>
         public BBIWARG(string[] args)
         {
             handleArgs(args);
@@ -73,11 +132,17 @@ namespace bbiwarg
 
         }
 
+        /// <summary>
+        /// Runs the main program.
+        /// </summary>
         public void run()
         {
             inputProvider.start();
         }
 
+        /// <summary>
+        /// Creates the input provider.
+        /// </summary>
         private void createInputProvider()
         {
             if (Parameters.InputSource == InputType.Movie)
@@ -86,18 +151,29 @@ namespace bbiwarg
                 inputProvider = new InputProvider();
         }
 
+        /// <summary>
+        /// Runs the debug window in its own thread.
+        /// </summary>
         private void debugWindowThreadStart()
         {
             debugWindow = new DebugWindow(inputProvider, inputHandler, Parameters.DebugWindowTitle, Parameters.DebugWindowUpdateIntervall);
             Application.Run(debugWindow);
         }
 
+        /// <summary>
+        /// Runs the glasses window in its own thread.
+        /// </summary>
         private void glassesWindowThreadStart()
         {
             glassesWindow = new GlassesWindow(inputProvider, inputHandler, Parameters.GlassesWindowTitle, Screen.AllScreens[1], Parameters.GlassesWindowUpdateInterval);
             Application.Run(glassesWindow);
         }
 
+        /// <summary>
+        /// Handles the event that the device has started by starting the enabled windows.
+        /// </summary>
+        /// <param name="sender">event sender</param>
+        /// <param name="e">event arguments</param>
         private void handleDeviceStartedEvent(object sender, EventArgs e)
         {
             if (debugWindowEnabled)
@@ -107,6 +183,10 @@ namespace bbiwarg
                 glassesWindowThread.Start();
         }
 
+        /// <summary>
+        /// Parses the command line arguments and sets parameters depending on them.
+        /// </summary>
+        /// <param name="args">command line arguments</param>
         private void handleArgs(String[] args)
         {
             if (args.Length > 0)

+ 3 - 1
bbiwarg/Images/EdgeImage.cs

@@ -33,7 +33,9 @@ namespace bbiwarg.Images
         public EdgeImage(DepthImage depthImage)
         {
             Size = depthImage.Size;
-            Image = depthImage.Image.ConvertScale<byte>(255f / (depthImage.MaxDepth - depthImage.MinDepth), 0).Canny(Parameters.EdgeImageCannyStartThreshold, Parameters.EdgeImageCannyLinkingThreshold, Parameters.EdgeImageCannySize).ThresholdBinary(new Gray(0), new Gray(1));
+            Image = depthImage.Image.ConvertScale<byte>(255f / (depthImage.MaxDepth - depthImage.MinDepth), 0).
+                Canny(Parameters.EdgeImageCannyStartThreshold, Parameters.EdgeImageCannyLinkingThreshold, Parameters.EdgeImageCannySize).
+                ThresholdBinary(new Gray(0), new Gray(1));
             RoughImage = Image.Dilate(Parameters.EdgeImageRoughNumDilationIterations);
         }
 

+ 1 - 1
bbiwarg/Output/DebugOutput/TouchEventVisualizer.cs

@@ -17,7 +17,7 @@ namespace bbiwarg.Output.DebugOutput
     class TouchEventVisualizer
     {
         /// <summary>
-        /// used to prevent the simultaneous access to <see cref="handleNewFrameData"/> and <see cref="getOutputImage"/> from different threads
+        /// used to prevent running <see cref="handleNewFrameData"/> and <see cref="getOutputImage"/> simultaneously from different threads
         /// </summary>
         private Object sync;
 

+ 382 - 27
bbiwarg/Parameters.cs

@@ -10,59 +10,192 @@ using bbiwarg.Utility;
 
 namespace bbiwarg
 {
+    /// <summary>
+    /// type of input source
+    /// </summary>
     public enum InputType
     {
         Camera,
         Movie
     }
 
-    class Parameters
+    /// <summary>
+    /// Defines all parameters used in the whole program.
+    /// </summary>
+    static class Parameters
     {
-        // console
+        #region console
+        
+        /// <summary>
+        /// with of the console in monospace characters
+        /// </summary>
         public static readonly int ConsoleWidth = 90;
+
+        /// <summary>
+        /// height of the console in monospace characters
+        /// </summary>
         public static readonly int ConsoleHeight = 30;
+        
+        #endregion
+
 
-        // input
+        #region input
+        
+        /// <summary>
+        /// the input source type
+        /// </summary>
         public static readonly InputType InputSource = InputType.Movie;
+
+        /// <summary>
+        /// path to the movie file used as input source
+        /// </summary>
         public static readonly String InputMoviePath = "..\\..\\videos\\touch\\4.skv";
 
-        // Logger
+        #endregion
+
+
+        #region Logger
+
+        /// <summary>
+        /// true iff the timer output should be shown
+        /// </summary>
         public static readonly bool LoggerTimerOutputEnabled = true;
+
+        /// <summary>
+        /// bitfield which specifies which subjects should be logged
+        /// </summary>
         public static readonly LogSubject LoggerEnabledSubjects = LogSubject.None;
 
-        // Debug window
+        #endregion
+
+
+        #region DebugWindow
+
+        /// <summary>
+        /// true iff the debug window is enabled
+        /// </summary>
         public static readonly bool DebugWindowEnabled = true;
+
+        /// <summary>
+        /// the update interval for the debug window
+        /// </summary>
         public static readonly int DebugWindowUpdateIntervall = 1000 / 30; // 30fps
+
+        /// <summary>
+        /// the title of the debug window
+        /// </summary>
         public static readonly String DebugWindowTitle = "BBIWARG - DebugOutput";
 
-        // glasses window
+        #endregion
+
+
+        #region GlassesWindow
+
+        /// <summary>
+        /// true iff the glasses window is enabled
+        /// </summary>
         public static readonly bool GlassesWindowEnabled = false;
+
+        /// <summary>
+        /// the update interval for the glasses window
+        /// </summary>
         public static readonly int GlassesWindowUpdateInterval = 1000 / 30; // 30fps
-        public static readonly String GlassesWindowTitle = "BBIWARG - GlassesOuty   put";
+
+        /// <summary>
+        /// the titel of the debug window
+        /// </summary>
+        public static readonly String GlassesWindowTitle = "BBIWARG - GlassesOutput";
+
+        /// <summary>
+        /// number of calibration points
+        /// </summary>
         public static readonly int GlassesWindowNumCalibrationPoints = 20;
 
-        // TUIO
+        #endregion
+
+
+        #region tuio
+
+        /// <summary>
+        /// true iff the tuio server is enabled
+        /// </summary>
         public static readonly bool TuioEnabledByDefault = true;
+
+        /// <summary>
+        /// the default ip address of the tuio server
+        /// </summary>
         public static readonly String TuioDefaultIP = "127.0.0.1";
+
+        /// <summary>
+        /// the default port of the tuio server
+        /// </summary>
         public static readonly Int16 TuioDefaultPort = 3333;
 
-        // confidence image
+        #endregion
+
+
+        #region ConfidenceImage
+
+        /// <summary>
+        /// the minimum confidence threshold for pixel values to be considered correct
+        /// </summary>
         public static readonly int ConfidenceImageMinThreshold = 500;
 
-        // depth image
+        #endregion
+
+
+        #region DepthImage
+
+        /// <summary>
+        /// the size of the median filter used to filter the depth image
+        /// </summary>
         public static readonly int DepthImageMedianSize = 5;
+
+        /// <summary>
+        /// the depth range which is considered important (in mm)
+        /// </summary>
         public static readonly int DepthImageDepthRange = 200; // <255
 
-        // edge image
+        #endregion
+
+
+        #region EdgeImage
+
+        /// <summary>
+        /// start threshold for the canny edge detector used to detect edges in the depth image
+        /// </summary>
         public static readonly int EdgeImageCannyStartThreshold = 80;
+
+        /// <summary>
+        /// linking threshold for the canny edge detector used to detect edges in the depth image 
+        /// </summary>
         public static readonly int EdgeImageCannyLinkingThreshold = 60;
+
+        /// <summary>
+        /// filter size for the canny edge detector used to detect edges in the depth image  
+        /// </summary>
         public static readonly int EdgeImageCannySize = 3;
+
+        /// <summary>
+        /// number of dilation iterations to generate the rough edge image from the edge image
+        /// </summary>
         public static readonly int EdgeImageRoughNumDilationIterations = 1;
 
-        // general tracking
+        #endregion
+
+
+        #region general tracking
+        
+        /// <summary>
+        /// if a tracked object moves this relative amount it will have a similarity of 0 to itself at the previous position
+        /// </summary>
         public static readonly float TrackerMaxRelativeMove = 0.25f;
 
-        // finger detection
+        #endregion
+
+
+        #region finger detection
+
         public static readonly int FingerStepSize = 1;
         public static readonly int FingerMaxGapCounter = 3;
         public static readonly int FingerMaxSliceDifferencePerStep = 5;
@@ -76,7 +209,11 @@ namespace bbiwarg
         public static readonly int FingerMaxCrippleDifference = 20;
         public static readonly int FingerContourMargin = 4;
 
-        // finger tracking
+        #endregion
+
+
+        #region finger tracking
+
         public static readonly int FingerTrackerNumFramesDetectedUntilTracked = 5;
         public static readonly int FingerTrackerNumFramesLostUntilDeleted = 10;
         public static readonly float FingermXX = 0.000005f;
@@ -86,7 +223,11 @@ namespace bbiwarg
         public static readonly float FingerTrackerMaxTipPointRelativeMove = TrackerMaxRelativeMove;
         public static readonly float FingerTrackerMaxHandPointRelativeMove = TrackerMaxRelativeMove;
 
-        // hand detection
+        #endregion
+
+
+        #region hand detection
+        
         public static readonly int HandNumColors = 3;
         public static readonly int HandFloodFillDownDiff = 2;
         public static readonly int HandFloodFillUpDiff = 2;
@@ -100,7 +241,11 @@ namespace bbiwarg
         public static readonly float HandThumbDefectMinShortLongLengthRatio = 0.3f;
         public static readonly float HandThumbDefectMaxShortLongLengthRatio = 0.7f;
 
-        // hand tracker
+        #endregion
+
+
+        #region hand tracker
+
         public static readonly int HandTrackerNumFramesDetectedUntilTracked = 5;
         public static readonly int HandTrackerNumFramesLostUntilDeleted = 5;
         public static readonly float HandTrackerMaxCentroidRelativeMove = TrackerMaxRelativeMove;
@@ -108,11 +253,19 @@ namespace bbiwarg
         public static readonly float HandmXY = 0.0f;
         public static readonly float HandmYY = 0.0005f;
 
-        // palm detection
+        #endregion
+
+
+        #region palm detection
+
         public static readonly int PalmNumPositionsForPalmWidth = 5;
         public static readonly float PalmInsideTolerance = 0.1f;
 
-        // palm tracker
+        #endregion
+
+
+        #region palm tracker
+
         public static readonly int PalmTrackerNumFramesDetectedUntilTracked = 5;
         public static readonly int PalmTrackerNumFramesLostUntilDeleted = 5;
         public static readonly float PalmTrackerMaxWristUpperRelativeMove = TrackerMaxRelativeMove;
@@ -123,11 +276,26 @@ namespace bbiwarg
         public static readonly float PalmmXY = 0.0f;
         public static readonly float PalmmYY = 0.00005f;
 
-        //palm Grid
+        #endregion
+
+
+        #region palm grid
+
+        /// <summary>
+        /// default number of palm grid rows
+        /// </summary>
         public static readonly int PalmGridDefaultNumRows = 3;
+
+        /// <summary>
+        /// default number of palm grid columns
+        /// </summary>
         public static readonly int PalmGridDefaultNumColumns = 4;
 
-        // touch detection
+        #endregion
+
+
+        #region touch
+
         public static readonly float TouchMinTouchValue = 0.3f;
         public static readonly int TouchAreaSize = 30;
         public static readonly int TouchFloodfillDownDiff = 1;
@@ -135,58 +303,245 @@ namespace bbiwarg
         public static readonly int TouchTipInsideFactor = 2;
         public static readonly int TouchTipOutsideFactor = 7;
 
-        // touch tracking
+        #endregion
+
+
+        #region touch tracking
+
+        /// <summary>
+        /// number of frames an object needs to be detected before it is tracked
+        /// </summary>
         public static readonly int TouchTrackerNumFramesDetectedUntilTracked = 1;
+
+        /// <summary>
+        /// number of frames an object needs to be lost before it is deleted
+        /// </summary>
         public static readonly int TouchTrackerNumFramesLostUntilDeleted = 5;
+
+        /// <summary>
+        /// if the absolute position of a tracked touch event moves this relative amount it will have a similarity of 0 to itself at the previous position
+        /// </summary>
         public static readonly float TouchTrackerMaxAbsolutePositionRelativeMove = TrackerMaxRelativeMove;
+
+        /// <summary>
+        /// xx entry for the measurement noise covariance matrix for the kalman filter used to smooth touch events
+        /// </summary>
         public static readonly float TouchmXX = 0.003f;
+
+        /// <summary>
+        /// xy and yx entry for the measurement noise covariance matrix for the kalman filter used to smooth touch events
+        /// </summary>
         public static readonly float TouchmXY = 0.0f;
+
+        /// <summary>
+        /// yy entry for the measurement noise covariance matrix for the kalman filter used to smooth touch events
+        /// </summary>
         public static readonly float TouchmYY = 0.00165f;
+
+        /// <summary>
+        /// value used for all entries in the process noise covariance matrix for the kalman filter used to smooth touch events
+        /// </summary>
         public static readonly float TouchProcessNoise = 3.0e-4f;
 
-        // touchEventVisualizer
+        #endregion
+
+
+        #region TouchEventVisualizer
+
+        /// <summary>
+        /// time in ms after which old touch events are removed from the touch event visualizer
+        /// </summary>
         public static readonly int TouchEventVisualizerFadeOutTime = 1500;
 
-        // homographyExport
+        #endregion
+
+
+        #region homographyExport
+
+        /// <summary>
+        /// file name of the file to which the homography is written
+        /// </summary>
         public static readonly String HomographyFileName = "homography.txt";
 
-        // colors
+        #endregion
+
+
+        #region colors
+
+        #region general
+
+        /// <summary>
+        /// color used to draw detected objects
+        /// </summary>
         public static readonly Color ColorDetected = Color.Turquoise;
+
+        /// <summary>
+        /// color used to draw tracked objects
+        /// </summary>
         public static readonly Color ColorTracked = Color.Yellow;
 
+        #endregion
+
+
+        #region images
+        
+        /// <summary>
+        /// color used to specify which color channels the depth image is drawn to
+        /// </summary>
         public static readonly Color DepthImageColor = Color.White;
+
+        /// <summary>
+        /// color used to specify which color channels the edge image is drawn to
+        /// </summary>
         public static readonly Color EdgeImageColor = Color.Blue;
+
+        /// <summary>
+        /// color used to draw the borders of the output images
+        /// </summary>
         public static readonly Color OutputImageBorderColor = Color.White;
 
+        #endregion
+
+
+        #region finger
+
+        /// <summary>
+        /// color used to draw the finger slices
+        /// </summary>
         public static readonly Color FingerSliceColor = Color.Magenta;
+
+        /// <summary>
+        /// color used to draw the detected fingers
+        /// </summary>
         public static readonly Color FingerDetectedColor = ColorDetected;
+
+        /// <summary>
+        /// color used to draw the tracked fingers
+        /// </summary>
         public static readonly Color FingerTrackedColor = ColorTracked;
+
+        /// <summary>
+        /// color used to draw the finger tip point
+        /// </summary>
         public static readonly Color FingerTipColor = Color.Blue;
+
+        /// <summary>
+        /// color used to draw the finger hand point
+        /// </summary>
         public static readonly Color FingerHandColor = Color.Yellow;
+
+        /// <summary>
+        /// color used to draw the finger contour
+        /// </summary>
         public static readonly Color FingerContourColor = Color.Red;
+
+        /// <summary>
+        /// color used to draw the text for the finger id
+        /// </summary>
         public static readonly Color FingerIDColor = Color.White;
 
+        #endregion
+
+
+        #region touch
+
+        /// <summary>
+        /// color used to draw detected touch events
+        /// </summary>
         public static readonly Color TouchEventDetectedColor = ColorDetected;
+
+        /// <summary>
+        /// color used to draw tracked touch events
+        /// </summary>
         public static readonly Color TouchEventTrackedColor = ColorTracked;
-        public static readonly Color TouchEventAreaMatchedSubtractColor = Color.DarkOrange;
-        public static readonly Color TouchEventAreaNonMatchedSubtractColor = Color.DarkSlateGray;
-        public static readonly Color TouchEventStatusBarColor = Color.Green;
 
+        #endregion
+
+
+        #region TouchEventVisualizer
+
+        /// <summary>
+        /// color used to draw the lines between touch events in the touch event visualizer
+        /// </summary>
         public static readonly Color TouchEventVisualizerLineColor = Color.Yellow;
+
+        /// <summary>
+        /// color used to draw the touch event points in the touch event visualizer
+        /// </summary>
         public static readonly Color TouchEventVisualizerPointColor = Color.Red;
+
+        /// <summary>
+        /// color used to draw the grid in the touch event visualizer
+        /// </summary>
         public static readonly Color TouchEventVisualizerGridColor = Color.White;
+
+        /// <summary>
+        /// color used to draw the text in the touch event visualizer
+        /// </summary>
         public static readonly Color TouchEventVisualizerTextColor = Color.White;
+
+        /// <summary>
+        /// color used to highlight the active block in the touch event visualizer
+        /// </summary>
         public static readonly Color TouchEventVisualizerActiveBlockColor = Color.DarkSlateGray;
 
+        #endregion
+
+
+        #region palm
+
+        /// <summary>
+        /// color used to draw the plam quadrangle
+        /// </summary>
         public static readonly Color PalmQuadColor = Color.Blue;
+
+        /// <summary>
+        /// color used to draw the palm grid in the palm
+        /// </summary>
         public static readonly Color PalmGridColor = Color.CornflowerBlue;
 
+        #endregion
+
+
+        #region hand
+
+        /// <summary>
+        /// colors used to draw the hands (ith element is a color which specifies the color channels used to draw the ith hand)
+        /// </summary>
         public static readonly Color[] HandColors = new Color[3] { Color.Red, Color.Blue, Color.Green };
+
+        /// <summary>
+        /// color used to draw the hand centroid
+        /// </summary>
         public static readonly Color HandCentroidColor = Color.Yellow;
+
+        /// <summary>
+        /// color used to draw the hand id text
+        /// </summary>
         public static readonly Color HandIDColor = Color.White;
+
+        /// <summary>
+        /// color used to draw the points of the thumb defects
+        /// </summary>
         public static readonly Color HandThumbDefectPointColor = Color.Lime;
+
+        /// <summary>
+        /// color used to draw the lines of the thumb defects
+        /// </summary>
         public static readonly Color HandThumbDefectLineColor = Color.CornflowerBlue;
 
+        #endregion
+
+
+        #region calibration
+
+        /// <summary>
+        /// color used to draw the calibration points in the glasses window
+        /// </summary>
         public static readonly Color CalibrationPointColor = Color.Yellow;
+
+        #endregion
+
+        #endregion
     }
 }

+ 14 - 0
bbiwarg/Utility/Logger.cs

@@ -6,6 +6,9 @@ using System.Threading.Tasks;
 
 namespace bbiwarg.Utility
 {
+    /// <summary>
+    /// flags describing the different log subjects
+    /// </summary>
     public enum LogSubject
     {
         None = 0,
@@ -22,10 +25,21 @@ namespace bbiwarg.Utility
         PalmTracker = 1024
     }
 
+    /// <summary>
+    /// Logs messages.
+    /// </summary>
     static class Logger
     {
+        /// <summary>
+        /// the current frame
+        /// </summary>
         public static int CurrentFrame { get; set; }
 
+        /// <summary>
+        /// May print a message depending on the subject and <see cref="Parameters.LoggerEnabledSubjects"/>.
+        /// </summary>
+        /// <param name="message">the message</param>
+        /// <param name="subject">the subject the message belongs to, determines if this message is printed</param>
         public static void log(string message, LogSubject subject)
         {
             if (Parameters.LoggerEnabledSubjects.HasFlag(subject))

+ 56 - 0
bbiwarg/Utility/Projection2DTo2D.cs

@@ -9,17 +9,54 @@ using Emgu.CV.Structure;
 
 namespace bbiwarg.Utility
 {
+    /// <summary>
+    /// Computes and stores a homography matrix and provides functions to export it and project points.
+    /// </summary>
     class Projection2DTo2D
     {
+        /// <summary>
+        /// size of the image the original points are in
+        /// </summary>
         private ImageSize sizeA;
+
+        /// <summary>
+        /// size of the image the projected points are in
+        /// </summary>
         private ImageSize sizeB;
+
+        /// <summary>
+        /// calibration points in the first image (match points in calibrationPointsB)
+        /// </summary>
         private List<PointF> calibrationPointsA;
+
+        /// <summary>
+        /// calibration points in the second image (match points in calibrationPointsA)
+        /// </summary>
         private List<PointF> calibrationPointsB;
+
+        /// <summary>
+        /// number of points used for the calibration
+        /// </summary>
         private int numPointsForCalibration;
+
+        /// <summary>
+        /// homography matrix used to compute the projected points
+        /// </summary>
         private HomographyMatrix homography;
 
+
+        /// <summary>
+        /// true iff the calibration is finished
+        /// </summary>
         public bool IsCalibrated { get; private set; }
 
+
+        /// <summary>
+        /// Constructs a Projection2DTo2D.
+        /// </summary>
+        /// <param name="sizeA">size of the image the original points are in</param>
+        /// <param name="sizeB">size of the image the projected points are in</param>
+        /// <param name="numPointsForCalibration">number of points used for the calibration</param>
         public Projection2DTo2D(ImageSize sizeA, ImageSize sizeB, int numPointsForCalibration = 4) {
             this.sizeA = sizeA;
             this.sizeB = sizeB;
@@ -28,6 +65,9 @@ namespace bbiwarg.Utility
             reset();
         }
 
+        /// <summary>
+        /// Resets the calibration.
+        /// </summary>
         public void reset() {
             homography = null;
             IsCalibrated = false;
@@ -35,6 +75,11 @@ namespace bbiwarg.Utility
             calibrationPointsB = new List<PointF>();
         }
 
+        /// <summary>
+        /// Adds a pair of calibration points.
+        /// </summary>
+        /// <param name="pointA">point in the first image</param>
+        /// <param name="pointB">point in the second image</param>
         public void addCalibrationPoints(Vector2D pointA, Vector2D pointB) {
             calibrationPointsA.Add(sizeA.getRelativePoint(pointA));
             calibrationPointsB.Add(sizeB.getRelativePoint(pointB));
@@ -43,12 +88,20 @@ namespace bbiwarg.Utility
                 calibrate();
         }
 
+        /// <summary>
+        /// Projects a point.
+        /// </summary>
+        /// <param name="pointA">the point to project</param>
+        /// <returns>projected point</returns>
         public Vector2D projectPoint(Vector2D pointA) {
             PointF[] pointfsB = new PointF[1] {sizeA.getRelativePoint(pointA)};
             homography.ProjectPoints(pointfsB);
             return sizeB.getAbsolutePoint(new Vector2D(pointfsB[0]));
         }
 
+        /// <summary>
+        /// Computes the homography from the lists of calibration points.
+        /// </summary>
         private void calibrate() {
             homography = CameraCalibration.FindHomography(calibrationPointsA.ToArray(), calibrationPointsB.ToArray(), Emgu.CV.CvEnum.HOMOGRAPHY_METHOD.DEFAULT, 0.995);
             
@@ -59,6 +112,9 @@ namespace bbiwarg.Utility
             exportHomography();
         }
 
+        /// <summary>
+        /// Writes the homography to a file.
+        /// </summary>
         private void exportHomography() {
             String[] fileData = new String[homography.Size.Height];
             StringBuilder sb = new StringBuilder();

+ 48 - 1
bbiwarg/Utility/Timer.cs

@@ -7,17 +7,56 @@ using System.Threading;
 
 namespace bbiwarg.Utility
 {
-    class Timer
+    /// <summary>
+    /// Stores and prints timing information for different code sections.
+    /// </summary>
+    static class Timer
     {
+        /// <summary>
+        /// used to prevent running <see cref="start"/>, <see cref="stop"/> and <see cref="outputAll"/> simultaneously from different threads
+        /// </summary>
         private static Object sync = new object();
+
+        /// <summary>
+        /// dictionary of stopwatches indexed by name of the code section
+        /// </summary>
         private static Dictionary<String, Stopwatch> stopwatches = new Dictionary<string, Stopwatch>();
+
+        /// <summary>
+        /// dictionary of current runtimes indexed by name of the code section
+        /// </summary>
         private static Dictionary<String, double> currentTimes = new Dictionary<string, double>();
+
+        /// <summary>
+        /// dictionary of minimum runtimes indexed by name of the code section
+        /// </summary>
         private static Dictionary<String, double> minTimes = new Dictionary<string, double>();
+
+        /// <summary>
+        /// dictionary of maximum runtimes indexed by name of the code section
+        /// </summary>
         private static Dictionary<String, double> maxTimes = new Dictionary<string, double>();
+
+        /// <summary>
+        /// dictionary of the sum of runtimes indexed by name of the code section
+        /// </summary>
         private static Dictionary<String, double> sumTimes = new Dictionary<string, double>();
+
+        /// <summary>
+        /// dictionary of the number of times the time was measured indexed by name of the code section
+        /// </summary>
         private static Dictionary<String, int> numTimes = new Dictionary<string, int>();
+
+        /// <summary>
+        /// the maximum length for the name of a code section
+        /// </summary>
         private static int maxNameLength = 1;
 
+
+        /// <summary>
+        /// Starts a timer for the given name and initializes the dictionaries when called for the first time with this name.
+        /// </summary>
+        /// <param name="name">name of the code section</param>
         public static void start(String name)
         {
             lock (sync)
@@ -36,6 +75,10 @@ namespace bbiwarg.Utility
             }
         }
 
+        /// <summary>
+        /// Stops the timer for the given name and stores timing information.
+        /// </summary>
+        /// <param name="name">name of the code section</param>
         public static void stop(String name)
         {
             lock (sync)
@@ -49,6 +92,10 @@ namespace bbiwarg.Utility
                 currentTimes[name] = time;
             }
         }
+
+        /// <summary>
+        /// Prints all collected timing information.
+        /// </summary>
         public static void outputAll()
         {
             lock (sync)