|
@@ -8,76 +8,130 @@ using bbiwarg.Images;
|
|
using bbiwarg.Graphics;
|
|
using bbiwarg.Graphics;
|
|
using bbiwarg.Recognition.Tracking;
|
|
using bbiwarg.Recognition.Tracking;
|
|
using bbiwarg.Utility;
|
|
using bbiwarg.Utility;
|
|
-using TUIO;
|
|
|
|
|
|
|
|
namespace bbiwarg.Recognition.TouchRecognition
|
|
namespace bbiwarg.Recognition.TouchRecognition
|
|
{
|
|
{
|
|
|
|
+ public class PalmTouchEventArgs : EventArgs
|
|
|
|
+ {
|
|
|
|
+ public int TrackID { get; private set; }
|
|
|
|
+ public Vector2D Position { get; private set; }
|
|
|
|
+
|
|
|
|
+ public PalmTouchEventArgs(int trackID, Vector2D position)
|
|
|
|
+ {
|
|
|
|
+ TrackID = trackID;
|
|
|
|
+ Position = position;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public delegate void PalmTouchEventHandler(object sender, PalmTouchEventArgs e);
|
|
|
|
+
|
|
class TouchTracker : Tracker<TouchEvent>
|
|
class TouchTracker : Tracker<TouchEvent>
|
|
{
|
|
{
|
|
public List<TouchEvent> TouchEvents { get { return TrackedObjects; } }
|
|
public List<TouchEvent> TouchEvents { get { return TrackedObjects; } }
|
|
- private TuioServer tuioServer;
|
|
|
|
- private Dictionary<int, TuioCursor> tuioCursors;
|
|
|
|
- private TouchEventVisualizer touchEventVisualizer;
|
|
|
|
|
|
+ public Dictionary<int, Kalman2DPositionFilter> kalmanFilters;
|
|
|
|
+ public event PalmTouchEventHandler PalmTouchDown;
|
|
|
|
+ public event PalmTouchEventHandler PalmTouchMove;
|
|
|
|
+ public event PalmTouchEventHandler PalmTouchUp;
|
|
|
|
+
|
|
|
|
+ protected virtual void OnPalmTouchDown(PalmTouchEventArgs e) { if (PalmTouchDown != null) PalmTouchDown(this, e); }
|
|
|
|
+ protected virtual void OnPalmTouchMove(PalmTouchEventArgs e) { if (PalmTouchMove != null) PalmTouchMove(this, e); }
|
|
|
|
+ protected virtual void OnPalmTouchUp(PalmTouchEventArgs e) { if (PalmTouchUp != null) PalmTouchUp(this, e); }
|
|
|
|
|
|
- public TouchTracker(TuioServer tuioServer, TouchEventVisualizer touchEventVisualizer)
|
|
|
|
|
|
+ public TouchTracker()
|
|
: base(Constants.TouchEventNumFramesDetectedUntilTracked, Constants.TouchEventNumFramesLostUntilDeleted, Constants.TouchEventMinSimilarityForTracking)
|
|
: base(Constants.TouchEventNumFramesDetectedUntilTracked, Constants.TouchEventNumFramesLostUntilDeleted, Constants.TouchEventMinSimilarityForTracking)
|
|
{
|
|
{
|
|
- this.tuioServer = tuioServer;
|
|
|
|
- this.tuioCursors = new Dictionary<int, TuioCursor>();
|
|
|
|
- this.touchEventVisualizer = touchEventVisualizer;
|
|
|
|
|
|
+ kalmanFilters = new Dictionary<int, Kalman2DPositionFilter>();
|
|
}
|
|
}
|
|
|
|
|
|
public new void reset() {
|
|
public new void reset() {
|
|
- tuioCursors.Clear();
|
|
|
|
- touchEventVisualizer.Reset();
|
|
|
|
|
|
+ foreach (int id in kalmanFilters.Keys) {
|
|
|
|
+ OnPalmTouchUp(new PalmTouchEventArgs(id, kalmanFilters[id].getPrediction()));
|
|
|
|
+ }
|
|
|
|
+ kalmanFilters.Clear();
|
|
base.reset();
|
|
base.reset();
|
|
}
|
|
}
|
|
|
|
|
|
- public new void updateFrame(List<TouchEvent> detectedObjects)
|
|
|
|
|
|
+ protected override void onDetect(object sender, EventArgs e)
|
|
{
|
|
{
|
|
- tuioServer.initFrame();
|
|
|
|
- base.updateFrame(detectedObjects);
|
|
|
|
- tuioServer.commitFrame();
|
|
|
|
- touchEventVisualizer.updateImage();
|
|
|
|
|
|
+ TrackableObjectHistory<TouchEvent> history = (TrackableObjectHistory<TouchEvent>)sender;
|
|
|
|
+ if (history.NumFramesInCurrentState == 1)
|
|
|
|
+ Logger.log("TouchEvent #" + history.ID.ToString() + " detected", LogSubject.TouchTracker);
|
|
}
|
|
}
|
|
|
|
|
|
- protected override void onStateChanged(object sender, TrackingStateChangeEventArgs e)
|
|
|
|
|
|
+ protected override void onTrack(object sender, EventArgs e)
|
|
{
|
|
{
|
|
TrackableObjectHistory<TouchEvent> history = (TrackableObjectHistory<TouchEvent>)sender;
|
|
TrackableObjectHistory<TouchEvent> history = (TrackableObjectHistory<TouchEvent>)sender;
|
|
|
|
+ if (history.NumFramesInCurrentState == 1)
|
|
|
|
+ Logger.log("TouchEvent #" + history.ID.ToString() + " tracked", LogSubject.TouchTracker);
|
|
|
|
+
|
|
|
|
+ if (history.LastObject is PalmTouchEvent)
|
|
|
|
+ {
|
|
|
|
+ PalmTouchEvent pte = (PalmTouchEvent)history.LastObject;
|
|
|
|
+ if (history.NumFramesInCurrentState == 1)
|
|
|
|
+ palmTouchDown(history.ID, pte.RelativePalmPosition);
|
|
|
|
+ else
|
|
|
|
+ palmTouchMove(history.ID, pte.RelativePalmPosition);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ protected override void onRetrack(object sender, EventArgs e)
|
|
|
|
+ {
|
|
|
|
+ TrackableObjectHistory<TouchEvent> history = (TrackableObjectHistory<TouchEvent>)sender;
|
|
|
|
+ if (history.NumFramesInCurrentState == 1)
|
|
|
|
+ Logger.log("TouchEvent #" + history.ID.ToString() + " retracked", LogSubject.TouchTracker);
|
|
|
|
+
|
|
|
|
+ if (history.LastObject is PalmTouchEvent)
|
|
|
|
+ {
|
|
|
|
+ PalmTouchEvent pte = (PalmTouchEvent)history.LastObject;
|
|
|
|
+ palmTouchMove(history.ID, pte.RelativePalmPosition);
|
|
|
|
+ }
|
|
|
|
+ else throw new ArgumentException();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ protected override void onLoose(object sender, EventArgs e)
|
|
|
|
+ {
|
|
|
|
+ TrackableObjectHistory<TouchEvent> history = (TrackableObjectHistory<TouchEvent>)sender;
|
|
|
|
+ if (history.NumFramesInCurrentState == 1)
|
|
|
|
+ Logger.log("TouchEvent #" + history.ID.ToString() + " lost", LogSubject.TouchTracker);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ protected override void onDelete(object sender, EventArgs e)
|
|
|
|
+ {
|
|
|
|
+ TrackableObjectHistory<TouchEvent> history = (TrackableObjectHistory<TouchEvent>)sender;
|
|
|
|
+ if (history.NumFramesInCurrentState == 1)
|
|
|
|
+ Logger.log("TouchEvent #" + history.ID.ToString() + " deleted", LogSubject.TouchTracker);
|
|
|
|
+
|
|
|
|
+ if (history.LastObject is PalmTouchEvent)
|
|
|
|
+ {
|
|
|
|
+ PalmTouchEvent pte = (PalmTouchEvent)history.LastObject;
|
|
|
|
+ palmTouchUp(history.ID, pte.RelativePalmPosition);
|
|
|
|
+ }
|
|
|
|
+ else throw new ArgumentException();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ private void palmTouchDown(int id, Vector2D relPos) {
|
|
|
|
+ Kalman2DPositionFilter kalmanFilter = new Kalman2DPositionFilter(Constants.TouchmXX, Constants.TouchmXY, Constants.TouchmYY, Constants.TouchProcessNoise);
|
|
|
|
+ kalmanFilter.setInitialPosition(relPos);
|
|
|
|
+ kalmanFilters.Add(id, kalmanFilter);
|
|
|
|
+ OnPalmTouchDown(new PalmTouchEventArgs(id, relPos));
|
|
|
|
+ Logger.log("TouchEvent #" + id.ToString() + " touchDown at (" + relPos.X + ", " + relPos.Y + ")", LogSubject.TouchEvents);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void palmTouchMove(int id, Vector2D relPos) {
|
|
|
|
+ Vector2D correctedRelPos = kalmanFilters[id].getCorrectedPosition(relPos);
|
|
|
|
+ OnPalmTouchMove(new PalmTouchEventArgs(id, correctedRelPos));
|
|
|
|
+ Logger.log("TouchEvent #" + id.ToString() + " touchMove to (" + relPos.X + ", " + relPos.Y + ")", LogSubject.TouchEvents);
|
|
|
|
+ }
|
|
|
|
|
|
- TouchEvent currentTouchEvent = history.LastObject;
|
|
|
|
- if (currentTouchEvent is PalmTouchEvent)
|
|
|
|
|
|
+ private void palmTouchUp(int id, Vector2D relPos) {
|
|
|
|
+ Kalman2DPositionFilter kalmanFilter;
|
|
|
|
+ if (kalmanFilters.TryGetValue(id, out kalmanFilter))
|
|
{
|
|
{
|
|
- PalmTouchEvent currentPalmTouchEvent = (PalmTouchEvent)currentTouchEvent;
|
|
|
|
- Vector2D currentRelativePosition = currentPalmTouchEvent.RelativePalmPosition;
|
|
|
|
- TuioCursor tuioCursor;
|
|
|
|
- switch (e.NextState)
|
|
|
|
- {
|
|
|
|
- case TrackingState.Tracked:
|
|
|
|
- if (tuioCursors.TryGetValue(history.ID, out tuioCursor))
|
|
|
|
- {
|
|
|
|
- tuioServer.updateTuioCursor(tuioCursor, currentRelativePosition.X, currentRelativePosition.Y);
|
|
|
|
- touchEventVisualizer.updateTouchEvent(history.ID, currentRelativePosition);
|
|
|
|
- Logger.log("TouchEvent #" + history.ID.ToString() + " touchMove to (" + currentRelativePosition.X + ", " + currentRelativePosition.Y + ")", LogSubject.TouchTracker);
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- TuioCursor newTuioCursor = tuioServer.addTuioCursor(currentRelativePosition.X, currentRelativePosition.Y);
|
|
|
|
- tuioCursors.Add(history.ID, newTuioCursor);
|
|
|
|
- touchEventVisualizer.addTouchEvent(history.ID, currentRelativePosition);
|
|
|
|
- Logger.log("TouchEvent #" + history.ID.ToString() + " touchDown at (" + currentRelativePosition.X + ", " + currentRelativePosition.Y + ")", LogSubject.TouchTracker);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
- case TrackingState.Delete:
|
|
|
|
- if (tuioCursors.TryGetValue(history.ID, out tuioCursor))
|
|
|
|
- {
|
|
|
|
- tuioServer.removeTuioCursor(tuioCursor);
|
|
|
|
- tuioCursors.Remove(history.ID);
|
|
|
|
- touchEventVisualizer.removeTouchEvent(history.ID);
|
|
|
|
- Logger.log("TouchEvent #" + history.ID.ToString() + " touchUp at (" + currentRelativePosition.X + ", " + currentRelativePosition.Y + ")", LogSubject.TouchTracker);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
|
|
+ Vector2D correctedRelPos = kalmanFilter.getCorrectedPosition(relPos);
|
|
|
|
+ OnPalmTouchUp(new PalmTouchEventArgs(id, correctedRelPos));
|
|
|
|
+ kalmanFilters.Remove(id);
|
|
|
|
+ Logger.log("TouchEvent #" + id.ToString() + " touchUp at (" + relPos.X + ", " + relPos.Y + ")", LogSubject.TouchEvents);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|