using bbiwarg.Images;
using bbiwarg.Input.InputProviding;
using bbiwarg.Recognition.FingerRecognition;
using bbiwarg.Recognition.HandRecognition;
using bbiwarg.Recognition.PalmRecognition;
using bbiwarg.Recognition.TouchRecognition;
using bbiwarg.Utility;
using System;
namespace bbiwarg.Input.InputHandling
{
///
/// signature for the event that a new frame is finished processing
///
/// sender of the event
/// event parameters
public delegate void NewProcessedFrameEventHandler(object sender, NewProcessedFrameEventArgs e);
///
/// Encapsulates the arguments for the event of finishing to process a new frame.
///
public class NewProcessedFrameEventArgs: EventArgs
{
///
/// the data of the processed frame
///
public FrameData FrameData { get; private set; }
///
/// Creates a new NewProcessedFrameEventArgs with given frame data.
///
/// frame data
public NewProcessedFrameEventArgs(FrameData frameData)
{
FrameData = frameData;
}
}
///
/// Handles new frames by coordinating and delegating the work to the image, detector and tracker classes.
/// Also provides an event and the data for the tuio server and the graphical output.
///
public class InputHandler
{
///
/// the input provider which provides the raw data
///
private InputProvider inputProvider;
///
/// set iff the source is a movie which is in the first frame again
///
private bool resetFlag;
///
/// the finger detector
///
private FingerDetector fingerDetector;
///
/// the hand detector
///
private HandDetector handDetector;
///
/// the palm detector
///
private PalmDetector palmDetector;
///
/// the touch detector
///
private TouchDetector touchDetector;
///
/// the finger tracker
///
private FingerTracker fingerTracker;
///
/// the hand tracker
///
private HandTracker handTracker;
///
/// the palm tracker
///
private PalmTracker palmTracker;
///
/// the touch tracker
///
private TouchTracker touchTracker;
///
/// the size of all images
///
public ImageSize ImageSize { get; private set; }
///
/// converts 2d and 3d coordinates into each other
///
public CoordinateConverter CoordinateConverter { get; private set; }
///
/// data for the current frame
///
public FrameData FrameData { get; private set; }
///
/// event which occures, when a new frame is finished processing
///
public event NewProcessedFrameEventHandler NewProcessedFrameEvent;
///
/// Constructs an InputHandler with an .
///
/// the input provider
public InputHandler(InputProvider inputProvider)
{
this.inputProvider = inputProvider;
initialize();
inputProvider.NewFrameEvent += handleNewFrame;
VideoInputProvider videoInputProvider = inputProvider as VideoInputProvider;
if (videoInputProvider != null)
videoInputProvider.MovieRestartedEvent += handleMovieRestart;
}
///
/// Initializes all components.
///
private void initialize()
{
ImageSize = new ImageSize(inputProvider.ImageWidth, inputProvider.ImageHeight);
CoordinateConverter = new CoordinateConverter(ImageSize, inputProvider.HFOV, inputProvider.VFOV);
resetFlag = false;
fingerDetector = new FingerDetector(CoordinateConverter);
handDetector = new HandDetector();
palmDetector = new PalmDetector();
touchDetector = new TouchDetector();
fingerTracker = new FingerTracker(ImageSize);
handTracker = new HandTracker(ImageSize);
palmTracker = new PalmTracker(ImageSize);
touchTracker = new TouchTracker(ImageSize);
}
///
/// Resets the trackers.
///
public void reset()
{
touchTracker.reset();
handTracker.reset();
palmTracker.reset();
fingerTracker.reset();
}
///
/// Handles a new frame event by processing the new frame using the image, detector and tracker classes.
///
/// the sender of the event
/// the arguments for the new frame event
public void handleNewFrame(object sender, NewFrameEventArgs e)
{
Timer.start("InputHandler.handleNewFrame");
FrameData frameData = new FrameData();
frameData.FrameID = e.FrameID;
frameData.ImageSize = ImageSize;
// reset flag
frameData.ResetFlag = resetFlag;
resetFlag = false;
// confidence image
Timer.start("InputHandler.handleNewFrame::createConfidenceImage");
frameData.ConfidenceImage = new ConfidenceImage(e.RawConfidenceData, ImageSize);
Timer.stop("InputHandler.handleNewFrame::createConfidenceImage");
// depth image
Timer.start("InputHandler.handleNewFrame::createDepthImage");
frameData.DepthImage = new DepthImage(e.RawDepthData, ImageSize, frameData.ConfidenceImage);
Timer.stop("InputHandler.handleNewFrame::createDepthImage");
// edge image
Timer.start("InputHandler.handleNewFrame::createEdgeImage");
frameData.EdgeImage = new EdgeImage(frameData.DepthImage);
Timer.stop("InputHandler.handleNewFrame::createEdgeImage");
// detect fingers
Timer.start("InputHandler.handleNewFrame::detectFingers");
fingerDetector.detectFingers(frameData);
Timer.stop("InputHandler.handleNewFrame::detectFingers");
// track fingers
Timer.start("InputHandler.handleNewFrame::trackFingers");
fingerTracker.trackFingers(frameData);
Timer.stop("InputHandler.handleNewFrame::trackFingers");
// detect hands
Timer.start("InputHandler.handleNewFrame::detectHands");
handDetector.detectHands(frameData);
Timer.stop("InputHandler.handleNewFrame::detectHands");
// track hands
Timer.start("InputHandler.handleNewFrame::trackHands");
handTracker.trackHands(frameData);
Timer.stop("InputHandler.handleNewFrame::trackHands");
// detect palms
Timer.start("InputHandler.handleNewFrame::detectPalms");
palmDetector.detectPalms(frameData);
Timer.stop("InputHandler.handleNewFrame::detectPalms");
// track palms
Timer.start("InputHandler.handleNewFrame::trackPalms");
palmTracker.trackPalms(frameData);
Timer.stop("InputHandler.handleNewFrame::trackPalms");
// detect touches
Timer.start("InputHandler.handleNewFrame::detectTouches");
touchDetector.detectTouches(frameData);
Timer.stop("InputHandler.handleNewFrame::detectTouches");
//track touches
Timer.start("InputHandler.handleNewFrame::trackTouches");
touchTracker.trackTouches(frameData);
Timer.stop("InputHandler.handleNewFrame::trackTouches");
Timer.start("InputHandler.handleNewFrame::exportResults");
FrameData = frameData;
if (NewProcessedFrameEvent != null)
NewProcessedFrameEvent(this, new NewProcessedFrameEventArgs(frameData));
Timer.stop("InputHandler.handleNewFrame::exportResults");
Timer.stop("InputHandler.handleNewFrame");
if (Parameters.LoggerTimerOutputEnabled)
Timer.outputAll();
}
///
/// Handles the event of a restart of the movie.
///
/// the sender of the event
/// the event arguments
private void handleMovieRestart(object sender, EventArgs e)
{
reset();
resetFlag = true;
}
}
}