VideoHandle.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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.Detectors.FingerDetection;
  10. using bbiwarg.Detectors.PalmDetection;
  11. using bbiwarg.Detectors.TouchDetection;
  12. using bbiwarg.Detectors.HandDetection;
  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 FingerDetector fingerDetector;
  40. private HandDetector handDetector;
  41. private PalmDetector palmDetector;
  42. private TouchDetector touchDetector;
  43. private PalmTouchDetector palmTouchDetector;
  44. private FingerTracker fingerTracker;
  45. private TouchTracker touchTracker;
  46. private TouchEventVisualizer touchEventVisualizer;
  47. private int videoFrame = 0;
  48. public VideoHandle(IInputProvider inputProvider)
  49. {
  50. this.inputProvider = inputProvider;
  51. //initialize trackers
  52. touchTracker = new TouchTracker();
  53. fingerTracker = new FingerTracker();
  54. }
  55. public void start()
  56. {
  57. palmDetector = new PalmDetector();
  58. inputProvider.init();
  59. inputProvider.start();
  60. inputProvider.updateFrame();
  61. processFrameUpdate();
  62. }
  63. public void stop()
  64. {
  65. inputProvider.stop();
  66. }
  67. public bool sourceIsMovie()
  68. {
  69. return inputProvider.sourceIsMovie();
  70. }
  71. public void reversePlay()
  72. {
  73. inputProvider.reversePlay();
  74. }
  75. public void pauseMovie()
  76. {
  77. inputProvider.pauseMovie();
  78. }
  79. public void unpauseMovie()
  80. {
  81. inputProvider.unpauseMovie();
  82. }
  83. public void nextFrame()
  84. {
  85. if (inputProvider.isActive())
  86. {
  87. inputProvider.releaseFrame();
  88. inputProvider.updateFrame();
  89. processFrameUpdate();
  90. }
  91. else
  92. {
  93. inputProvider.stop();
  94. }
  95. videoFrame++;
  96. }
  97. public List<PalmTouchEvent> getPalmTouchEvents()
  98. {
  99. return palmTouchDetector.PalmTouchEvents;
  100. }
  101. private void processFrameUpdate()
  102. {
  103. Timer.start("processFrameUpdate");
  104. //read data from inputProvider
  105. Timer.start("readInputData");
  106. inputFrame = inputProvider.getInputFrame();
  107. Width = inputFrame.Width;
  108. Height = inputFrame.Height;
  109. Timer.stop("readInputData");
  110. //create output images
  111. Timer.start("createOtherImages");
  112. int numImages = 4;
  113. OutputImages = new OutputImage[numImages];
  114. for (int i = 0; i < numImages; i++) {
  115. OutputImages[i] = new OutputImage(Width, Height);
  116. }
  117. Timer.stop("createOtherImages");
  118. //create depthImage
  119. Timer.start("createDepthImage");
  120. Image<Gray, Int16> image = new Image<Gray, Int16>(Width, Height, Width * 2, inputFrame.RawDepthData);
  121. depthImage = new DepthImage(image, OutputImages[0]);
  122. Image<Gray, byte> tmpDepth = (depthImage.MaxDepth - depthImage.MinDepth) - depthImage.Image;
  123. OutputImages[0].Image[0] = OutputImages[0].Image[1] = OutputImages[0].Image[2] = tmpDepth;
  124. Timer.stop("createDepthImage");
  125. // create edge image
  126. Timer.start("createEdgeImage");
  127. edgeImage = new EdgeImage(depthImage);
  128. OutputImages[1].Image[2] = edgeImage.Image.ThresholdBinary(new Gray(0), new Gray(1)).Mul(255);
  129. Timer.stop("createEdgeImage");
  130. //detect fingers
  131. Timer.start("fingerDetection");
  132. fingerDetector = new FingerDetector(depthImage, edgeImage, OutputImages[1]);
  133. Timer.stop("fingerDetection");
  134. //track fingers
  135. Timer.start("fingerTracking");
  136. fingerTracker.setDetectedTouchEventsThisFrame(fingerDetector.Fingers, OutputImages[1]);
  137. Timer.stop("fingerTracking");
  138. //detect hands
  139. Timer.start("handDetection");
  140. handDetector = new HandDetector(depthImage, fingerTracker.TrackedFingers);
  141. Timer.stop("handDetection");
  142. //remove background noise
  143. Timer.start("removeBackground");
  144. depthImage.removeBackground(fingerDetector.Fingers);
  145. edgeImage = new EdgeImage(depthImage);
  146. OutputImages[2].Image[0] = OutputImages[2].Image[1] = OutputImages[2].Image[2] = (depthImage.MaxDepth - depthImage.MinDepth) - depthImage.Image;
  147. Timer.stop("removeBackground");
  148. OutputImage palm = new OutputImage(Width, Height);
  149. //detect palm
  150. Timer.start("palmDetection");
  151. if (CurrentFrame == 0)
  152. palmDetector.reset();
  153. palmDetector.findPalmQuad(depthImage, edgeImage, OutputImages[2], fingerDetector.Fingers);
  154. Timer.stop("palmDetection");
  155. //detect touchEvents
  156. Timer.start("touchDetection");
  157. touchDetector = new TouchDetector(fingerTracker.TrackedFingers, depthImage, OutputImages[0]);
  158. if (palmDetector.PalmQuad != null)
  159. palmTouchDetector = new PalmTouchDetector(touchDetector.TouchEvents, palmDetector.PalmQuad);
  160. Timer.stop("touchDetection");
  161. //track touchEvents
  162. Timer.start("touchTracking");
  163. touchTracker.setDetectedTouchEventsThisFrame(touchDetector.TouchEvents, OutputImages[2]);
  164. Timer.stop("touchTracking");
  165. // touch event visualizer
  166. if (touchEventVisualizer == null)
  167. touchEventVisualizer = new TouchEventVisualizer(Width, Height);
  168. if (CurrentFrame == 0)
  169. touchEventVisualizer.Reset();
  170. if (palmTouchDetector != null)
  171. {
  172. foreach (PalmTouchEvent e in palmTouchDetector.PalmTouchEvents)
  173. touchEventVisualizer.addPalmTouchEvent(e, CurrentFrame);
  174. touchEventVisualizer.updateImage();
  175. OutputImages[3] = touchEventVisualizer.OutputImage;
  176. }
  177. // add borders
  178. for (int i = 0; i < numImages; i++)
  179. {
  180. OutputImages[i].drawRectangle(0, 0, Width - 1, Height - 1, Color.White);
  181. }
  182. OutputImages = new OutputImage[] {OutputImages[0], OutputImages[1], OutputImages[2], palmDetector.i1, palmDetector.i2,
  183. palmDetector.i3, palmDetector.i5, palmDetector.i6, palmDetector.i7, palmDetector.i8, palmDetector.i9};
  184. Timer.stop("processFrameUpdate");
  185. }
  186. }
  187. }