using BBIWARG.Input.InputHandling;
using BBIWARG.Recognition.FingerRecognition;
using BBIWARG.Recognition.HandRecognition;
using BBIWARG.Recognition.PalmRecognition;
using BBIWARG.Recognition.TouchRecognition;
using Emgu.CV;
using Emgu.CV.Structure;
using System.Drawing;
namespace BBIWARG.Output.DebugOutput
{
///
/// DebugImageCreator creates all debug images as objects using the frame data.
///
internal class DebugImageCreator
{
///
/// visualizes touch events
///
private TouchEventVisualizer touchEventVisualizer;
///
/// the depth image with additional interesting points
///
public OutputImage DepthImage { get; private set; }
///
/// the edge image with all detected fingers drawn into it
///
public OutputImage FingerImage { get; private set; }
///
/// image showing detected hands in different colors
///
public OutputImage HandImage { get; private set; }
///
/// image showing the palm grid
///
public OutputImage PalmImage { get; private set; }
///
/// image showing the touch events in a grid
///
public OutputImage TouchImage { get; private set; }
///
/// Creates a DebugImageCreator.
///
/// the touchEventVisualizer used to generate the TouchImage
public DebugImageCreator(TouchEventVisualizer touchEventVisualizer)
{
this.touchEventVisualizer = touchEventVisualizer;
}
///
/// Updates all debug images.
///
/// data for the new frame
/// number of rows in the palm grid
/// number of columns in the palm grid
public void updateImages(FrameData frameData, int palmGridNumRows, int palmGridNumColumns)
{
updateDepthImage(frameData);
updateFingerImage(frameData);
updateHandImage(frameData);
updatePalmImage(frameData, palmGridNumRows, palmGridNumColumns);
updateTouchImage(frameData, palmGridNumRows, palmGridNumColumns);
}
///
/// Updates the depth image.
///
/// data for the new frame
private void updateDepthImage(FrameData frameData)
{
if (DepthImage != null)
DepthImage.Dispose();
DepthImage = new OutputImage(frameData.ImageSize);
// background (depth image)
DepthImage.drawImage((frameData.DepthImage.MaxDepth - frameData.DepthImage.MinDepth) - frameData.DepthImage.Image, Parameters.DepthImageColor);
// finger tips
foreach (Finger f in frameData.TrackedFingers)
{
Color tipColor = (f.Touch != null) ? Parameters.TouchEventDetectedColor : Parameters.FingerTipColor;
Color handColor = Parameters.FingerHandColor;
DepthImage.fillCircle(f.TipPoint, 5, tipColor);
DepthImage.fillCircle(f.HandPoint, 5, handColor);
}
// border
DepthImage.drawBorder(Parameters.OutputImageBorderColor);
}
///
/// Updates the finger image.
///
/// data for the new frame
private void updateFingerImage(FrameData frameData)
{
if (FingerImage != null)
FingerImage.Dispose();
FingerImage = new OutputImage(frameData.ImageSize);
// background (edge image)
FingerImage.drawImage(frameData.EdgeImage.Image.ThresholdBinary(new Gray(0), new Gray(255)), Parameters.EdgeImageColor);
// draw fingers
foreach (Finger f in frameData.TrackedFingers)
{
foreach (FingerSlice slice in f.SliceTrail.Slices)
FingerImage.drawLineSegment(slice.LineSegment, Parameters.FingerSliceColor);
FingerImage.drawContour(f.getContour(Parameters.FingerContourMargin), Parameters.FingerContourColor);
FingerImage.drawLineSegment(f.LineSegment, Parameters.FingerTrackedColor);
FingerImage.drawText(f.MidPoint, f.TrackID.ToString(), Parameters.FingerIDColor);
}
// border
FingerImage.drawBorder(Parameters.OutputImageBorderColor);
}
///
/// Updates the hand image.
///
/// data for the new frame
private void updateHandImage(FrameData frameData)
{
if (HandImage != null)
HandImage.Dispose();
HandImage = new OutputImage(frameData.ImageSize);
foreach (Hand h in frameData.DetectedHands)
{
HandImage.drawImage(h.Mask.ThresholdBinary(new Gray(0), new Gray(255)), Parameters.HandColors[h.TrackID % Parameters.HandNumColors]);
HandImage.fillCircle(h.Centroid, 5, Parameters.HandCentroidColor);
HandImage.drawText(h.Centroid, h.TrackID.ToString(), Parameters.HandIDColor);
if (h.Palm != null)
HandImage.drawDefect(h.Palm.ThumbDefect, Parameters.HandThumbDefectPointColor, Parameters.HandThumbDefectLineColor);
}
// border
HandImage.drawBorder(Parameters.OutputImageBorderColor);
}
///
/// Updates the palm image.
///
/// data for the new frame
/// number of rows in the palm grid
/// number of columns in the palm grid
private void updatePalmImage(FrameData frameData, int numRows, int numColumns)
{
if (PalmImage != null)
PalmImage.Dispose();
PalmImage = new OutputImage(frameData.ImageSize);
// handMask
Image handMask = new Image(frameData.ImageSize.Width, frameData.ImageSize.Height);
foreach (Hand h in frameData.TrackedHands)
handMask = handMask.Or(h.Mask);
// background
PalmImage.drawImage((frameData.DepthImage.MaxDepth - frameData.DepthImage.MinDepth) - frameData.DepthImage.Image.Or(255 - handMask.ThresholdBinary(new Gray(0), new Gray(255))), Parameters.DepthImageColor);
foreach (Touch t in frameData.TrackedTouches)
PalmImage.fillCircle(t.AbsolutePosition, 5, Parameters.TouchEventTrackedColor);
foreach (Palm p in frameData.TrackedPalms)
PalmImage.drawQuadrangleGrid(p.Quad, Parameters.PalmQuadColor, Parameters.PalmGridColor, numRows, numColumns);
// border
PalmImage.drawBorder(Parameters.OutputImageBorderColor);
}
///
/// Updates the touch image.
///
/// data for the new frame
/// number of rows in the palm grid
/// number of columns in the palm grid
private void updateTouchImage(FrameData frameData, int numRows, int numColumns)
{
if (TouchImage != null)
TouchImage.Dispose();
TouchImage = touchEventVisualizer.getOutputImage(frameData.ImageSize,
numRows,
numColumns,
Parameters.PalmSliderPos,
Parameters.PalmSliderMax,
Parameters.PalmSliderCurr);
}
}
}