VideoHandle.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Diagnostics;
  8. using bbiwarg.Utility;
  9. using bbiwarg.Recognition.FingerRecognition;
  10. using bbiwarg.Recognition.PalmRecognition;
  11. using bbiwarg.Recognition.TouchRecognition;
  12. using bbiwarg.Recognition.HandRecognition;
  13. using bbiwarg.Images;
  14. using bbiwarg.InputProviders;
  15. using Emgu.CV;
  16. using Emgu.CV.Structure;
  17. using bbiwarg.Graphics;
  18. namespace bbiwarg
  19. {
  20. class VideoHandle
  21. {
  22. private IInputProvider inputProvider;
  23. private InputFrame inputFrame;
  24. public int Width { get; private set; }
  25. public int Height { get; private set; }
  26. public int CurrentFrame
  27. {
  28. get
  29. {
  30. if (sourceIsMovie())
  31. return inputProvider.getCurrentMovieFrame();
  32. else
  33. return videoFrame;
  34. }
  35. }
  36. public OutputImage[] OutputImages { get; private set; }
  37. private DepthImage depthImage;
  38. private EdgeImage edgeImage;
  39. private ConfidenceImage confidenceImage;
  40. private FingerDetector fingerDetector;
  41. private HandDetector handDetector;
  42. private PalmDetector palmDetector;
  43. private TouchDetector touchDetector;
  44. private PalmTouchDetector palmTouchDetector;
  45. private FingerTracker fingerTracker;
  46. private TouchTracker touchTracker;
  47. private TouchEventVisualizer touchEventVisualizer;
  48. private int videoFrame = 0;
  49. public VideoHandle(IInputProvider inputProvider)
  50. {
  51. this.inputProvider = inputProvider;
  52. }
  53. public void start()
  54. {
  55. palmDetector = new PalmDetector();
  56. inputProvider.init();
  57. inputProvider.start();
  58. inputProvider.updateFrame();
  59. processFrameUpdate();
  60. }
  61. public void stop()
  62. {
  63. inputProvider.stop();
  64. }
  65. public bool sourceIsMovie()
  66. {
  67. return inputProvider.sourceIsMovie();
  68. }
  69. public void reversePlay()
  70. {
  71. inputProvider.reversePlay();
  72. }
  73. public void pauseMovie()
  74. {
  75. inputProvider.pauseMovie();
  76. }
  77. public void unpauseMovie()
  78. {
  79. inputProvider.unpauseMovie();
  80. }
  81. public void nextFrame()
  82. {
  83. if (inputProvider.isActive())
  84. {
  85. inputProvider.releaseFrame();
  86. inputProvider.updateFrame();
  87. processFrameUpdate();
  88. }
  89. else
  90. {
  91. inputProvider.stop();
  92. }
  93. videoFrame++;
  94. }
  95. public List<PalmTouchEvent> getPalmTouchEvents()
  96. {
  97. return palmTouchDetector.PalmTouchEvents;
  98. }
  99. private void processFrameUpdate()
  100. {
  101. Timer.start("processFrameUpdate");
  102. if (CurrentFrame == 0) {
  103. //initialize trackers
  104. touchTracker = new TouchTracker();
  105. fingerTracker = new FingerTracker();
  106. }
  107. //read data from inputProvider
  108. Timer.start("readInputData");
  109. inputFrame = inputProvider.getInputFrame();
  110. Width = inputFrame.Width;
  111. Height = inputFrame.Height;
  112. Timer.stop("readInputData");
  113. //create output images
  114. Timer.start("createOutputImages");
  115. OutputImages = new OutputImage[Constants.OutputNumImages];
  116. for (int i = 0; i < Constants.OutputNumImages; i++) {
  117. OutputImages[i] = new OutputImage(Width, Height);
  118. }
  119. Timer.stop("createOutputImages");
  120. //create confidenceImage
  121. Timer.start("createConfidenceImage");
  122. Image<Gray, Int16> rawConfidenceImage = new Image<Gray, Int16>(Width, Height, Width * 2, inputFrame.RawConfidenceData);
  123. confidenceImage = new ConfidenceImage(rawConfidenceImage);
  124. Timer.stop("createConfidenceImage");
  125. //create depthImage
  126. Timer.start("createDepthImage");
  127. Image<Gray, Int16> rawDepthImage = new Image<Gray, Int16>(Width, Height, Width * 2, inputFrame.RawDepthData);
  128. rawDepthImage = rawDepthImage.Or((1 - confidenceImage.Mask).Convert<Gray, Int16>().Mul(Int16.MaxValue));
  129. depthImage = new DepthImage(rawDepthImage);
  130. OutputImages[0].Image[0] = OutputImages[0].Image[1] = OutputImages[0].Image[2] = (depthImage.MaxDepth - depthImage.MinDepth) - depthImage.Image;
  131. Timer.stop("createDepthImage");
  132. // create edge image
  133. Timer.start("createEdgeImage");
  134. edgeImage = new EdgeImage(depthImage);
  135. OutputImages[1].Image[2] = edgeImage.Image.Mul(255);
  136. Timer.stop("createEdgeImage");
  137. //detect fingers
  138. Timer.start("fingerDetection");
  139. fingerDetector = new FingerDetector(depthImage, edgeImage, OutputImages[1]);
  140. Timer.stop("fingerDetection");
  141. //track fingers
  142. Timer.start("fingerTracking");
  143. fingerTracker.setDetectedTouchEventsThisFrame(fingerDetector.Fingers, OutputImages[1]);
  144. Timer.stop("fingerTracking");
  145. //detect hands
  146. Timer.start("handDetection");
  147. handDetector = new HandDetector(depthImage, edgeImage, fingerDetector.Fingers, OutputImages[2]);
  148. Timer.stop("handDetection");
  149. //remove background noise
  150. Timer.start("removeBackground");
  151. OutputImages[3].Image[0] = OutputImages[3].Image[1] = OutputImages[3].Image[2] = (depthImage.MaxDepth - depthImage.MinDepth) - depthImage.Image.Or(255-handDetector.HandMask);
  152. Timer.stop("removeBackground");
  153. //detect palm
  154. Timer.start("palmDetection");
  155. if (CurrentFrame == 0)
  156. palmDetector.reset();
  157. palmDetector.findPalmQuad(OutputImages[3], handDetector.Hands);
  158. Timer.stop("palmDetection");
  159. //detect touchEvents
  160. Timer.start("touchDetection");
  161. touchDetector = new TouchDetector(fingerTracker.TrackedFingers, depthImage, OutputImages[0]);
  162. if (palmDetector.PalmQuad != null)
  163. palmTouchDetector = new PalmTouchDetector(touchDetector.TouchEvents, palmDetector.PalmQuad);
  164. Timer.stop("touchDetection");
  165. //track touchEvents
  166. Timer.start("touchTracking");
  167. touchTracker.setDetectedTouchEventsThisFrame(touchDetector.TouchEvents, OutputImages[3]);
  168. Timer.stop("touchTracking");
  169. // touch event visualizer
  170. if (touchEventVisualizer == null)
  171. touchEventVisualizer = new TouchEventVisualizer(Width, Height);
  172. if (CurrentFrame == 0)
  173. touchEventVisualizer.Reset();
  174. if (palmTouchDetector != null)
  175. {
  176. foreach (PalmTouchEvent e in palmTouchDetector.PalmTouchEvents)
  177. {
  178. touchEventVisualizer.addPalmTouchEvent(e, CurrentFrame);
  179. }
  180. touchEventVisualizer.updateImage();
  181. OutputImages[4] = touchEventVisualizer.OutputImage;
  182. }
  183. // add borders
  184. for (int i = 0; i < Constants.OutputNumImages; i++)
  185. {
  186. OutputImages[i].drawRectangle(0, 0, Width - 1, Height - 1, Color.White);
  187. }
  188. Timer.stop("processFrameUpdate");
  189. }
  190. }
  191. }