Browse Source

documented Output

Daniel Kauth 10 years ago
parent
commit
3011ec28f9

+ 5 - 1
bbiwarg/Input/InputHandling/FrameData.cs

@@ -52,6 +52,7 @@ namespace bbiwarg.Input.InputHandling
         /// a list of fingers detected in this frame
         /// </summary>
         public List<Finger> DetectedFingers { get; set; }
+
         /// <summary>
         /// a list of fingers which are tracked in this frame
         /// </summary>
@@ -62,6 +63,7 @@ namespace bbiwarg.Input.InputHandling
         /// a list of hands detected in this frame
         /// </summary>
         public List<Hand> DetectedHands { get; set; }
+
         /// <summary>
         /// a list of hands which are tracked in this frame
         /// </summary>
@@ -72,6 +74,7 @@ namespace bbiwarg.Input.InputHandling
         /// a list of plams detected in this frame
         /// </summary>
         public List<Palm> DetectedPalms { get; set; }
+
         /// <summary>
         /// a list of plams which are tracked in this frame
         /// </summary>
@@ -82,14 +85,15 @@ namespace bbiwarg.Input.InputHandling
         /// a list of <see cref="Touch"/> objects detected in this frame
         /// </summary>
         public List<Touch> DetectedTouches { get; set; }
+
         /// <summary>
         /// a list of <see cref="Touch"/> objects which are tracked in this frame
         /// </summary>
         public List<Touch> TrackedTouches { get; set; }
+
         /// <summary>
         /// a list of touch events generated in this frame
         /// </summary>
         public List<TouchEvent> TouchEvents { get; set; }
-
     }
 }

+ 61 - 0
bbiwarg/Output/DebugOutput/DebugImageCreator.cs

@@ -14,21 +14,58 @@ using Emgu.CV;
 
 namespace bbiwarg.Output.DebugOutput
 {
+    /// <summary>
+    /// DebugImageCreator creates all debug images as <see cref="OutputImage"/> objects using the frame data.
+    /// </summary>
     class DebugImageCreator
     {
+        /// <summary>
+        /// visualizes touch events
+        /// </summary>
         private TouchEventVisualizer touchEventVisualizer;
 
+
+        /// <summary>
+        /// the depth image with additional interesting points
+        /// </summary>
         public OutputImage DepthImage { get; private set; }
+
+        /// <summary>
+        /// the edge image with all detected fingers drawn into it
+        /// </summary>
         public OutputImage FingerImage { get; private set; }
+
+        /// <summary>
+        /// image showing detected hands in diffrent colors
+        /// </summary>
         public OutputImage HandImage { get; private set; }
+
+        /// <summary>
+        /// image showing the palm grid
+        /// </summary>
         public OutputImage PalmImage { get; private set; }
+
+        /// <summary>
+        /// image showing the touch events in a grid
+        /// </summary>
         public OutputImage TouchImage { get; private set; }
 
+
+        /// <summary>
+        /// Creates a DebugImageCreator.
+        /// </summary>
+        /// <param name="touchEventVisualizer">the touchEventVisualizer used to generate the TouchImage</param>
         public DebugImageCreator(TouchEventVisualizer touchEventVisualizer)
         {
             this.touchEventVisualizer = touchEventVisualizer;
         }
 
+        /// <summary>
+        /// Updates all debug images.
+        /// </summary>
+        /// <param name="frameData">data for the new frame</param>
+        /// <param name="palmGridNumRows">number of rows in the palm grid</param>
+        /// <param name="palmGridNumColumns">number of columns in the palm grid</param>
         public void updateImages(FrameData frameData, int palmGridNumRows, int palmGridNumColumns)
         {
             updateDepthImage(frameData);
@@ -38,6 +75,10 @@ namespace bbiwarg.Output.DebugOutput
             updateTouchImage(frameData, palmGridNumRows, palmGridNumColumns);
         }
 
+        /// <summary>
+        /// Updates the depth image.
+        /// </summary>
+        /// <param name="frameData">data for the new frame</param>
         private void updateDepthImage(FrameData frameData)
         {
             if (DepthImage != null)
@@ -61,6 +102,10 @@ namespace bbiwarg.Output.DebugOutput
             DepthImage.drawBorder(Parameters.OutputImageBorderColor);
         }
 
+        /// <summary>
+        /// Updates the finger image.
+        /// </summary>
+        /// <param name="frameData">data for the new frame</param>
         private void updateFingerImage(FrameData frameData)
         {
             if (FingerImage != null)
@@ -85,6 +130,10 @@ namespace bbiwarg.Output.DebugOutput
             FingerImage.drawBorder(Parameters.OutputImageBorderColor);
         }
 
+        /// <summary>
+        /// Updates the hand image.
+        /// </summary>
+        /// <param name="frameData">data for the new frame</param>
         private void updateHandImage(FrameData frameData)
         {
             if (HandImage != null)
@@ -107,6 +156,12 @@ namespace bbiwarg.Output.DebugOutput
             HandImage.drawBorder(Parameters.OutputImageBorderColor);
         }
 
+        /// <summary>
+        /// Updates the palm image.
+        /// </summary>
+        /// <param name="frameData">data for the new frame</param>
+        /// <param name="numRows">number of rows in the palm grid</param>
+        /// <param name="numColumns">number of columns in the palm grid</param>
         private void updatePalmImage(FrameData frameData, int numRows, int numColumns)
         {
             if (PalmImage != null)
@@ -131,6 +186,12 @@ namespace bbiwarg.Output.DebugOutput
             PalmImage.drawBorder(Parameters.OutputImageBorderColor);
         }
 
+        /// <summary>
+        /// Updates the touch image.
+        /// </summary>
+        /// <param name="frameData">data for the new frame</param>
+        /// <param name="numRows">number of rows in the palm grid</param>
+        /// <param name="numColumns">number of columns in the palm grid</param>
         private void updateTouchImage(FrameData frameData, int numRows, int numColumns) {
             if (TouchImage != null)
                 TouchImage.Dispose();

+ 79 - 0
bbiwarg/Output/DebugOutput/DebugWindow.cs

@@ -15,15 +15,49 @@ using Emgu.CV.UI;
 
 namespace bbiwarg.Output.DebugOutput
 {
+    /// <summary>
+    /// A Windows Form which shows the debug images.
+    /// </summary>
     public partial class DebugWindow : Form
     {
+        /// <summary>
+        /// the input handler
+        /// </summary>
         private InputHandler inputHandler;
+
+        /// <summary>
+        /// the input provider
+        /// </summary>
         private InputProvider inputProvider;
+
+        /// <summary>
+        /// the debug image creator
+        /// </summary>
         private DebugImageCreator debugImageCreator;
+
+        /// <summary>
+        /// timer to periodically update the window
+        /// </summary>
         private System.Windows.Forms.Timer timer;
+
+        /// <summary>
+        /// id of the current frame
+        /// </summary>
         private int currentFrameID;
+
+        /// <summary>
+        /// true iff the window is showing the latest data
+        /// </summary>
         private bool guiUpToDate;
 
+
+        /// <summary>
+        /// Creates the DebugWindow.
+        /// </summary>
+        /// <param name="inputProvider">input provider</param>
+        /// <param name="inputHandler">input handle</param>
+        /// <param name="name">the title of the window</param>
+        /// <param name="updateInterval">the update interval for the window in ms</param>
         public DebugWindow(InputProvider inputProvider, InputHandler inputHandler, String name, int updateInterval)
         {
             InitializeComponent();
@@ -51,12 +85,21 @@ namespace bbiwarg.Output.DebugOutput
             timer.Start();
         }
 
+        /// <summary>
+        /// Stops the input provider when closing the window.
+        /// </summary>
+        /// <param name="e">event arguments</param>
         protected override void OnClosing(CancelEventArgs e)
         {
             base.OnClosing(e);
             inputProvider.stop();
         }
 
+        /// <summary>
+        /// Updates the window.
+        /// </summary>
+        /// <param name="sender">the event sender</param>
+        /// <param name="e">the event arguments</param>
         private void update(object sender, EventArgs e)
         {
             Utility.Timer.start("DebugWindow.update");
@@ -87,6 +130,10 @@ namespace bbiwarg.Output.DebugOutput
             Utility.Timer.stop("DebugWindow.update");
         }
 
+        /// <summary>
+        /// Updates the debug images.
+        /// </summary>
+        /// <param name="frameData">data for the new frame</param>
         private void updateImages(FrameData frameData) {
             guiUpToDate = false;
 
@@ -95,6 +142,9 @@ namespace bbiwarg.Output.DebugOutput
             debugImageCreator.updateImages(frameData, numRows, numColumns);            
         }
 
+        /// <summary>
+        /// Updates the gui elements.
+        /// </summary>
         private void updateGUI() {
             // update image boxes
             depthImageBox.Image = debugImageCreator.DepthImage;
@@ -109,21 +159,39 @@ namespace bbiwarg.Output.DebugOutput
             guiUpToDate = true;
         }
 
+        /// <summary>
+        /// Handles the click on the play / pause button.
+        /// </summary>
+        /// <param name="sender">event sender</param>
+        /// <param name="e">event arguments</param>
         private void playPauseButton_Click(object sender, EventArgs e)
         {
             handlePlayPause();
         }
 
+        /// <summary>
+        /// Handles the click on the next frame button.
+        /// </summary>
+        /// <param name="sender">event sender</param>
+        /// <param name="e">event arguments</param>
         private void nextFrameButton_Click(object sender, EventArgs e)
         {
             handleGoToNextFrame();
         }
 
+        /// <summary>
+        /// Handles the click on the previous frame button.
+        /// </summary>
+        /// <param name="sender">event sender</param>
+        /// <param name="e">event arguments</param>
         private void previousFrameButton_Click(object sender, EventArgs e)
         {
             handleGoToPreviousFrame();
         }
 
+        /// <summary>
+        /// Toggles the paused state of the movie.
+        /// </summary>
         private void handlePlayPause() {
             VideoInputProvider videoInputProvider = inputProvider as VideoInputProvider;
 
@@ -142,17 +210,28 @@ namespace bbiwarg.Output.DebugOutput
             }
         }
 
+        /// <summary>
+        /// Jumps to the next movie frame.
+        /// </summary>
         private void handleGoToNextFrame() {
             VideoInputProvider videoInputProvider = inputProvider as VideoInputProvider;
             videoInputProvider.goToNextFrame();
         }
 
+        /// <summary>
+        /// Jumps to the previous movie frame.
+        /// </summary>
         private void handleGoToPreviousFrame()
         {
             VideoInputProvider videoInputProvider = inputProvider as VideoInputProvider;
             videoInputProvider.goToPreviousFrame();
         }
 
+        /// <summary>
+        /// Updates the window when the number of rows or columns in the palm grid are changed.
+        /// </summary>
+        /// <param name="sender">event sender</param>
+        /// <param name="e">event arguments</param>
         private void palmGridTrackBar_Scroll(object sender, EventArgs e)
         {
             currentFrameID = -1;

+ 49 - 2
bbiwarg/Output/DebugOutput/TouchEventVisualizer.cs

@@ -11,22 +11,55 @@ using bbiwarg.Input.InputHandling;
 
 namespace bbiwarg.Output.DebugOutput
 {
+    /// <summary>
+    /// Provides an image showing touch events.
+    /// </summary>
     class TouchEventVisualizer
     {
+        /// <summary>
+        /// used to prevent the simultaneous access to <see cref="handleNewFrameData"/> and <see cref="getOutputImage"/> from different threads
+        /// </summary>
         private Object sync;
+
+        /// <summary>
+        /// used to store the relative time at which the touch events occured
+        /// </summary>
         private Stopwatch timer;
 
+
+        /// <summary>
+        /// all touch events starting at the last TouchDown, indexed by a unique id
+        /// </summary>
         private Dictionary<int, List<Vector2D>> activeTouches;
+
+        /// <summary>
+        /// old touch events which are stored for a limited time, indexed by a unique id
+        /// </summary>
         private Dictionary<int, List<Vector2D>> oldTouches;
+
+        /// <summary>
+        /// relative times of last frame updates which are stored for a limited time, indexed by a unique id
+        /// </summary>
         private Dictionary<int, long> lastUpdates;
+
+        /// <summary>
+        /// the next free id, used as a unique id for the dictionaries
+        /// </summary>
         private int nextFreeID;
 
+
+        /// <summary>
+        /// Creates a TouchEventVisualizer.
+        /// </summary>
         public TouchEventVisualizer()
         {
             sync = new object();
             reset();
         }
 
+        /// <summary>
+        /// Resets the touch events and the timer.
+        /// </summary>
         public void reset()
         {
             timer = new Stopwatch();
@@ -39,6 +72,11 @@ namespace bbiwarg.Output.DebugOutput
 
         }
 
+        /// <summary>
+        /// Handles the event that a new frame is finished processing by updating the touch events.
+        /// </summary>
+        /// <param name="sender">event sender</param>
+        /// <param name="e">event arguments</param>
         public void handleNewFrameData(object sender, NewProcessedFrameEventArgs e)
         {
             FrameData frameData = e.FrameData;
@@ -72,6 +110,13 @@ namespace bbiwarg.Output.DebugOutput
                 }
         }
 
+        /// <summary>
+        /// Returns an output image showing the touch events.
+        /// </summary>
+        /// <param name="imageSize">output image size</param>
+        /// <param name="numRows">number of rows in the palm grid</param>
+        /// <param name="numColumns">number columns in the palm grid</param>
+        /// <returns>image showing touch events</returns>
         public OutputImage getOutputImage(ImageSize imageSize, int numRows, int numColumns)
         {
             lock (sync)
@@ -142,10 +187,12 @@ namespace bbiwarg.Output.DebugOutput
             }
         }
 
+        /// <summary>
+        /// Removes old touch events and update times.
+        /// </summary>
+        /// <param name="breakTime">every touch event which occured before breakTime is removed</param>
         private void removeOldPositions(long breakTime)
         {
-            long currentTime = timer.ElapsedMilliseconds;
-
             List<int> ids = new List<int>(lastUpdates.Keys);
             for (int i = ids.Count - 1; i >= 0; i--)
             {

+ 87 - 0
bbiwarg/Output/GlassesOutput/GlassesWindow.cs

@@ -16,21 +16,80 @@ using Emgu.CV.UI;
 
 namespace bbiwarg.Output.GlassesOutput
 {
+    /// <summary>
+    /// A Windows Form which displays a fullscreen window to be shown on augmented reality glasses.
+    /// </summary>
     public partial class GlassesWindow : Form
     {
+        /// <summary>
+        /// the input provider
+        /// </summary>
         private InputProvider inputProvider;
+
+        /// <summary>
+        /// the input handler
+        /// </summary>
         private InputHandler inputHandler;
+
+        /// <summary>
+        /// timer to periodically update the window
+        /// </summary>
         private System.Windows.Forms.Timer timer;
+
+        /// <summary>
+        /// id of the current frame
+        /// </summary>
         private int currentFrameID;
+
+        /// <summary>
+        /// true iff the window is showing the latest data
+        /// </summary>
         private bool guiUpToDate;
+
+        /// <summary>
+        /// size of the input images
+        /// </summary>
         private ImageSize inputSize;
+
+        /// <summary>
+        /// size of the image show on the glasses
+        /// </summary>
         private ImageSize outputSize;
+
+        /// <summary>
+        /// the image shown on the glasses
+        /// </summary>
         private OutputImage image;
+
+        /// <summary>
+        /// projection from the input image plane to a plane which lies in front of the wearer of the glasses (output plane)
+        /// </summary>
         private Projection2DTo2D projection;
+
+        /// <summary>
+        /// position of the current calibration point in the output plane
+        /// </summary>
         private Vector2D currentCalibrationPoint;
+
+        /// <summary>
+        /// true iff the calibration image has the latest data
+        /// </summary>
         private bool calibrationImageUpToDate;
+
+        /// <summary>
+        /// random number generator
+        /// </summary>
         private Random rand;
 
+
+        /// <summary>
+        /// Creates a GlassesWindow.
+        /// </summary>
+        /// <param name="inputProvider">input provider</param>
+        /// <param name="inputHandler">input handler</param>
+        /// <param name="name">title of the window</param>
+        /// <param name="screen">the screen this window is shown on</param>
+        /// <param name="updateInterval">the update interval for the window in ms</param>
         public GlassesWindow(InputProvider inputProvider, InputHandler inputHandler, String name, Screen screen, int updateInterval)
         {
             InitializeComponent();
@@ -62,12 +121,21 @@ namespace bbiwarg.Output.GlassesOutput
             Size = screen.Bounds.Size;
         }
 
+        /// <summary>
+        /// Stops the input provider when closing the window.
+        /// </summary>
+        /// <param name="e">event arguments</param>
         protected override void OnClosing(CancelEventArgs e)
         {
             base.OnClosing(e);
             inputProvider.stop();
         }
 
+        /// <summary>
+        /// Updates the window.
+        /// </summary>
+        /// <param name="sender">the event sender</param>
+        /// <param name="e">the event arguments</param>
         private void update(object sender, EventArgs e)
         {
             Utility.Timer.start("GlassesWindow.update");
@@ -108,6 +176,10 @@ namespace bbiwarg.Output.GlassesOutput
             Utility.Timer.stop("GlassesWindow.update");
         }
 
+        /// <summary>
+        /// Updates the glasses image.
+        /// </summary>
+        /// <param name="frameData">data for the new frame</param>
         private void updateImage(FrameData frameData)
         {
             guiUpToDate = false;
@@ -135,6 +207,9 @@ namespace bbiwarg.Output.GlassesOutput
 
         }
 
+        /// <summary>
+        /// Updates the calibration image.
+        /// </summary>
         private void updateCalibrationImage()
         {
             guiUpToDate = false;
@@ -146,6 +221,9 @@ namespace bbiwarg.Output.GlassesOutput
             image.fillCircle(currentCalibrationPoint, 25, Color.Orange);
         }
 
+        /// <summary>
+        /// Updates the gui elements.
+        /// </summary>
         private void updateGUI()
         {
             // update image boxes
@@ -154,6 +232,11 @@ namespace bbiwarg.Output.GlassesOutput
             guiUpToDate = true;
         }
 
+        /// <summary>
+        /// Handle key down events by showing the next point or finishing or resetting the calibration.
+        /// </summary>
+        /// <param name="sender">event sender</param>
+        /// <param name="e">event arguments</param>
         private void GlassesWindow_OnKeyDown(object sender, KeyEventArgs e)
         {
             if (e.KeyCode == Keys.K)
@@ -182,6 +265,10 @@ namespace bbiwarg.Output.GlassesOutput
             }
         }
 
+        /// <summary>
+        /// Returns a random point in the glasses image.
+        /// </summary>
+        /// <returns></returns>
         private Vector2D getRandomOutputPoint()
         {
             return outputSize.getAbsolutePoint(new Vector2D((float)rand.NextDouble(), (float)rand.NextDouble()));

+ 94 - 14
bbiwarg/Output/OutputImage.cs

@@ -11,43 +11,72 @@ using Emgu.CV.Structure;
 
 namespace bbiwarg.Output
 {
+    /// <summary>
+    /// An <see cref="Image"/> which provides additional drawing functions.
+    /// </summary>
     class OutputImage : Image<Rgb, byte>
     {
+        /// <summary>
+        /// Creates an OutputImage.
+        /// </summary>
+        /// <param name="width">image width</param>
+        /// <param name="height">image height</param>
         public OutputImage(int width, int height)
             : base(width, height)
         {
         }
 
+        /// <summary>
+        /// Creates an OutputImage.
+        /// </summary>
+        /// <param name="size">image size</param>
         public OutputImage(ImageSize size)
             : base(size.Width, size.Height)
         {
         }
 
 
-        public Color getColotAt(int x, int y)
+        /// <summary>
+        /// Returns the color at a position.
+        /// </summary>
+        /// <param name="x">x coordinate of the position</param>
+        /// <param name="y">y coordinate of the position</param>
+        /// <returns>color at position (x, y)</returns>
+        public Color getColorAt(int x, int y)
         {
-
             byte red = Data[y, x, 0];
             byte green = Data[y, x, 1];
             byte blue = Data[y, x, 2];
             return Color.FromArgb(red, green, blue);
         }
 
+        /// <summary>
+        /// Draws a line segment.
+        /// </summary>
+        /// <param name="lineSegment">line segment to draw</param>
+        /// <param name="color">color used to draw the line segment</param>
+        /// <param name="thickness">thickness of the line segment</param>
         public void drawLineSegment(bbiwarg.Utility.LineSegment2D lineSegment, Color color, int thickness = 1)
         {
             Draw(new Emgu.CV.Structure.LineSegment2D(lineSegment.P1, lineSegment.P2), new Rgb(color), thickness);
         }
 
+        /// <summary>
+        /// Draws a contour.
+        /// </summary>
+        /// <param name="contour">contour to draw</param>
+        /// <param name="color">color used to draw the contour</param>
+        /// <param name="thickness">thickness of the contour</param>
         public void drawContour(Contour<Point> contour, Color color, int thickness = 1)
         {
             Draw(contour, new Rgb(color), thickness);
         }
 
-        public void drawPoints(Seq<Point> points, Color color, int thickness = 1)
-        {
-            Draw(points, new Rgb(color), thickness);
-        }
-
+        /// <summary>
+        /// Colors a pixel.
+        /// </summary>
+        /// <param name="position">position of the pixel</param>
+        /// <param name="color">new color for pixel</param>
         public void drawPixel(Point position, Color color)
         {
             Data[position.Y, position.X, 0] = color.R;
@@ -55,27 +84,56 @@ namespace bbiwarg.Output
             Data[position.Y, position.X, 0] = color.B;
         }
 
+        /// <summary>
+        /// Draws a filled circle.
+        /// </summary>
+        /// <param name="position">center of the circle</param>
+        /// <param name="radius">radius of the circle</param>
+        /// <param name="color">color used to draw the circle</param>
         public void fillCircle(Point position, float radius, Color color)
         {
             Draw(new CircleF(position, radius), new Rgb(color), 0);
         }
 
+        /// <summary>
+        /// Draws a filled rectangle.
+        /// </summary>
+        /// <param name="rect">the rectangle</param>
+        /// <param name="color">color used to fill the rectangle</param>
         public void fillRectangle(Rectangle rect, Color color)
         {
             Draw(rect, new Rgb(color), -1);
         }
 
+        /// <summary>
+        /// Draws a unfilled rectangle.
+        /// </summary>
+        /// <param name="rect">the rectangle</param>
+        /// <param name="color">color used to raw the rectangle</param>
+        /// <param name="thichness">thickness of the rectangle</param>
         public void drawRectangle(Rectangle rect, Color color, int thichness = 0)
         {
             Draw(rect, new Rgb(color), thichness);
         }
 
+        /// <summary>
+        /// Draws text.
+        /// </summary>
+        /// <param name="position">top left corner to draw the text at</param>
+        /// <param name="text">the text to draw</param>
+        /// <param name="color">color used to draw the text</param>
         public void drawText(Point position, String text, Color color)
         {
             MCvFont font = new MCvFont(Emgu.CV.CvEnum.FONT.CV_FONT_HERSHEY_PLAIN, 1, 1);
             Draw(text, ref font, position, new Rgb(color));
         }
 
+        /// <summary>
+        /// Draws a convexity defect.
+        /// </summary>
+        /// <param name="defect">the defect to draw</param>
+        /// <param name="pointColor">color used to draw the points of the defect</param>
+        /// <param name="lineColor">color used to draw the lines of the defect</param>
         public void drawDefect(ConvexityDefect defect, Color pointColor, Color lineColor)
         {
             drawLineSegment(new Utility.LineSegment2D(defect.OuterShort, defect.Inner), lineColor);
@@ -87,9 +145,16 @@ namespace bbiwarg.Output
 
         }
 
+        /// <summary>
+        /// Draws a grid into a quadrangle.
+        /// </summary>
+        /// <param name="quad">the quadrangle</param>
+        /// <param name="borderColor">color used to draw the border lines</param>
+        /// <param name="gridColor">color used to draw the grid</param>
+        /// <param name="numRows">number of rows in the grid</param>
+        /// <param name="numCols">number of columns in the grid</param>
         public void drawQuadrangleGrid(Quadrangle quad, Color borderColor, Color gridColor, int numRows, int numCols)
         {
-
             Vector2D a = quad.TopLeft;
             Vector2D b = quad.TopRight;
             Vector2D c = quad.BottomRight;
@@ -116,11 +181,21 @@ namespace bbiwarg.Output
             drawLineSegment(new bbiwarg.Utility.LineSegment2D(d, a), borderColor);
         }
 
+        /// <summary>
+        /// Draws a border around the image.
+        /// </summary>
+        /// <param name="color">color used to draw the border</param>
         public void drawBorder(Color color)
         {
             drawRectangle(new Rectangle(0, 0, Width, Height), color);
         }
 
+        /// <summary>
+        /// Draws a touch gesture as the current point and a faded line.
+        /// </summary>
+        /// <param name="positions">touch positions</param>
+        /// <param name="scale">scale used to transform given positions into positions in the image</param>
+        /// <param name="opacity">opacity of the faded lines</param>
         public void drawTouchGesture(List<Vector2D> positions, Vector2D scale, float opacity = 1)
         {
             int numPositions = positions.Count;
@@ -136,28 +211,33 @@ namespace bbiwarg.Output
             fillCircle(lastPos, 3, pointColorFaded);
         }
 
+        /// <summary>
+        /// Draws a grayscale image into channels of the image.  
+        /// </summary>
+        /// <param name="image">the image to draw</param>
+        /// <param name="color">if a color component is != 0 the corresponding image channel is drawn to and image is scaled by (color component value / 255)</param>
         public void drawImage(Image<Gray, byte> image, Color color)
         {
             if (color.R != 0)
             {
                 if (color.R != byte.MaxValue)
-                    this[0] = this[0].Or(image.Mul((float)color.R / byte.MaxValue));
+                    this[0] = image.Mul((float)color.R / byte.MaxValue);
                 else
-                    this[0] = this[0].Or(image);
+                    this[0] = image;
             }
             if (color.G != 0)
             {
                 if (color.G != byte.MaxValue)
-                    this[1] = this[1].Or(image.Mul((float)color.G / byte.MaxValue));
+                    this[1] = image.Mul((float)color.G / byte.MaxValue);
                 else
-                    this[1] = this[1].Or(image);
+                    this[1] = image;
             }
             if (color.B != 0)
             {
                 if (color.B != byte.MaxValue)
-                    this[2] = this[2].Or(image.Mul((float)color.B / byte.MaxValue));
+                    this[2] = image.Mul((float)color.B / byte.MaxValue);
                 else
-                    this[2] = this[2].Or(image);
+                    this[2] = image;
             }
         }
     }