GlassesWindow.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows.Forms;
  10. using bbiwarg.Input.InputHandling;
  11. using bbiwarg.Input.InputProviding;
  12. using bbiwarg.Utility;
  13. using bbiwarg.Recognition.FingerRecognition;
  14. using bbiwarg.Recognition.PalmRecognition;
  15. using Emgu.CV.UI;
  16. namespace bbiwarg.Output.GlassesOutput
  17. {
  18. public partial class GlassesWindow : Form
  19. {
  20. private InputProvider inputProvider;
  21. private InputHandler inputHandler;
  22. private System.Windows.Forms.Timer timer;
  23. private int currentFrameID;
  24. private bool guiUpToDate;
  25. private ImageSize inputSize;
  26. private ImageSize outputSize;
  27. private OutputImage image;
  28. private Projection2DTo2D projection;
  29. private Vector2D currentCalibrationPoint;
  30. private bool calibrationImageUpToDate;
  31. private Random rand;
  32. public GlassesWindow(InputProvider inputProvider, InputHandler inputHandler, String name, Screen screen, int updateInterval)
  33. {
  34. InitializeComponent();
  35. this.inputProvider = inputProvider;
  36. this.inputHandler = inputHandler;
  37. this.inputSize = inputHandler.ImageSize;
  38. this.outputSize = new ImageSize(screen.Bounds.Width, screen.Bounds.Height);
  39. guiUpToDate = false;
  40. calibrationImageUpToDate = false;
  41. rand = new Random();
  42. currentCalibrationPoint = getRandomOutputPoint();
  43. projection = new Projection2DTo2D(inputSize, outputSize, Parameters.GlassesWindowNumCalibrationPoints);
  44. Name = name;
  45. Text = name;
  46. timer = new System.Windows.Forms.Timer();
  47. timer.Interval = updateInterval;
  48. timer.Tick += update;
  49. timer.Start();
  50. KeyPreview = true;
  51. //fullscreen
  52. FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
  53. Location = screen.Bounds.Location;
  54. Size = screen.Bounds.Size;
  55. }
  56. protected override void OnClosing(CancelEventArgs e)
  57. {
  58. base.OnClosing(e);
  59. inputProvider.stop();
  60. }
  61. private void update(object sender, EventArgs e)
  62. {
  63. Utility.Timer.start("GlassesWindow.update");
  64. if (!inputProvider.IsActive)
  65. Close();
  66. if (projection.IsCalibrated)
  67. {
  68. FrameData frameData = inputHandler.FrameData;
  69. if (frameData != null)
  70. {
  71. lock (frameData)
  72. {
  73. if (currentFrameID != frameData.FrameID)
  74. {
  75. currentFrameID = frameData.FrameID;
  76. Utility.Timer.start("GlassesWindow.update::updateImage");
  77. updateImage(frameData);
  78. Utility.Timer.stop("GlassesWindow.update::updateImage");
  79. }
  80. }
  81. }
  82. }
  83. else
  84. {
  85. if (!calibrationImageUpToDate)
  86. updateCalibrationImage();
  87. }
  88. if (!guiUpToDate)
  89. {
  90. Utility.Timer.start("GlassesWindow.update::updateGUI");
  91. updateGUI();
  92. Utility.Timer.stop("GlassesWindow.update::updateGUI");
  93. }
  94. Utility.Timer.stop("GlassesWindow.update");
  95. }
  96. private void updateImage(FrameData frameData)
  97. {
  98. guiUpToDate = false;
  99. if (image != null)
  100. image.Dispose();
  101. image = new OutputImage(outputSize);
  102. foreach (Palm palm in frameData.TrackedPalms)
  103. {
  104. Quadrangle quadInput = palm.Quad;
  105. Vector2D a = projection.projectPoint(quadInput.TopLeft);
  106. Vector2D b = projection.projectPoint(quadInput.TopRight);
  107. Vector2D c = projection.projectPoint(quadInput.BottomRight);
  108. Vector2D d = projection.projectPoint(quadInput.BottomLeft);
  109. Quadrangle quadOutput = new Quadrangle(a, b, c, d);
  110. image.drawQuadrangleGrid(quadOutput, Color.Yellow, Color.Orange, 3, 4);
  111. }
  112. foreach (Finger finger in frameData.TrackedFingers)
  113. {
  114. Vector2D tipProjected = projection.projectPoint(finger.TipPoint);
  115. image.fillCircle(tipProjected, 10, Color.Yellow);
  116. }
  117. }
  118. private void updateCalibrationImage()
  119. {
  120. guiUpToDate = false;
  121. if (image != null)
  122. image.Dispose();
  123. image = new OutputImage(outputSize);
  124. image.fillCircle(currentCalibrationPoint, 25, Color.Orange);
  125. }
  126. private void updateGUI()
  127. {
  128. // update image boxes
  129. imageBox.Image = image;
  130. guiUpToDate = true;
  131. }
  132. private void GlassesWindow_OnKeyDown(object sender, KeyEventArgs e)
  133. {
  134. if (e.KeyCode == Keys.K)
  135. {
  136. FrameData frameData = inputHandler.FrameData;
  137. if (frameData != null)
  138. {
  139. lock (frameData)
  140. {
  141. if (frameData.TrackedFingers.Count == 1)
  142. {
  143. Vector2D pointOutput = currentCalibrationPoint;
  144. Vector2D pointInput = frameData.TrackedFingers[0].TipPoint;
  145. projection.addCalibrationPoints(pointInput, pointOutput);
  146. currentCalibrationPoint = getRandomOutputPoint();
  147. }
  148. }
  149. }
  150. }
  151. else if (e.KeyCode == Keys.R)
  152. {
  153. projection.reset();
  154. currentCalibrationPoint = getRandomOutputPoint();
  155. }
  156. }
  157. private Vector2D getRandomOutputPoint()
  158. {
  159. return outputSize.getAbsolutePoint(new Vector2D((float)rand.NextDouble(), (float)rand.NextDouble()));
  160. }
  161. }
  162. }