VideoHandle.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  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 MathNet.Numerics.LinearAlgebra.Single;
  8. using bbiwarg.Images;
  9. using bbiwarg.InputProviders;
  10. using bbiwarg.Detectors;
  11. using bbiwarg.Helpers;
  12. namespace bbiwarg.VideoHandles
  13. {
  14. class VideoHandle
  15. {
  16. private IInputProvider inputProvider;
  17. private ForeFingerDetection foreFingerDetection;
  18. private PalmDetection palmDetection;
  19. private DepthImage depthImage;
  20. private ConfidenceImage confidenceImage;
  21. private UVImage uvImage;
  22. private ColorImage colorImage;
  23. private DepthImage handImage;
  24. private Int16[] segmentationDepth;
  25. private int[] histogram;
  26. private float maxU;
  27. private float maxV;
  28. public VideoHandle(IInputProvider inputProvider) {
  29. this.inputProvider = inputProvider;
  30. inputProvider.init();
  31. inputProvider.start();
  32. inputProvider.updateFrame();
  33. foreFingerDetection = new ForeFingerDetection(inputProvider, this);
  34. palmDetection = new PalmDetection(inputProvider, this);
  35. createImageData();
  36. maxU = (float)(Math.Tan(inputProvider.getHFOV() / 2f));
  37. maxV = (float)(Math.Tan(inputProvider.getVFOV() / 2f));
  38. }
  39. ~VideoHandle()
  40. {
  41. //inputProvider.stop();
  42. }
  43. public void nextFrame()
  44. {
  45. if (inputProvider.isActive())
  46. {
  47. inputProvider.releaseFrame();
  48. inputProvider.updateFrame();
  49. createImageData();
  50. }
  51. else {
  52. inputProvider.stop();
  53. }
  54. }
  55. public int getWidth()
  56. {
  57. return depthImage.getWidth();
  58. }
  59. public int getHeight()
  60. {
  61. return depthImage.getHeight();
  62. }
  63. private void createImageData()
  64. {
  65. depthImage = inputProvider.getDepthImage();
  66. handImage = inputProvider.getDepthImage();
  67. confidenceImage = inputProvider.getConfidenceImage();
  68. uvImage = inputProvider.getUVImage();
  69. colorImage = inputProvider.getColorImage();
  70. handImage.filterMedian(3);
  71. Int16 minDepth = handImage.getMinDepth();
  72. handImage.thresholdDepth(minDepth, minDepth + 200);
  73. histogram = handImage.getSmoothedHistogram();
  74. segmentationDepth = handImage.getSegmentationDepth();
  75. handImage.thresholdBinary((Int16) (segmentationDepth[1]+minDepth));
  76. }
  77. public Int16[] getSegementationDepth()
  78. {
  79. return segmentationDepth;
  80. }
  81. public int[] getSmoothedHistogram()
  82. {
  83. return histogram;
  84. }
  85. public short getDepth(int x, int y)
  86. {
  87. return depthImage.getDepth(x, y);
  88. }
  89. public short getConfidence(int x, int y)
  90. {
  91. return confidenceImage.getConfidence(x, y);
  92. }
  93. public Color getColor(int x, int y)
  94. {
  95. float u = uvImage.getU(x, y);
  96. float v = uvImage.getV(x, y);
  97. if (u < 0 || v < 0)
  98. return Color.Black;
  99. int colorImageWidth = colorImage.getWidth();
  100. int colorImageHeight = colorImage.getHeight();
  101. int xInColorImage = (int)(u * colorImageWidth) % colorImageWidth;
  102. int yInColorImage = (int)(v * colorImageHeight) % colorImageHeight;
  103. return colorImage.getColor(xInColorImage, yInColorImage);
  104. }
  105. public DepthImage getHandImage()
  106. {
  107. return handImage;
  108. }
  109. public DetectionStatus[] getFingerStatus(uint handIndex)
  110. {
  111. return inputProvider.getFingerStatus(handIndex);
  112. }
  113. public Vector[] getFingerTipPositions3D(uint handIndex)
  114. {
  115. return inputProvider.getFingerTipPositions3D(handIndex);
  116. }
  117. public Vector getPalmPosition3D(uint handIndex)
  118. {
  119. return inputProvider.getPalmPosition3D(handIndex);
  120. }
  121. public Vector getPalmNormal3D(uint handIndex)
  122. {
  123. return inputProvider.getPalmNormal3D(handIndex);
  124. }
  125. public Vector getForearmPosition3D(uint handIndex)
  126. {
  127. return inputProvider.getForearmPosition3D(handIndex);
  128. }
  129. public Vector getForeFingerPosition3D(uint handIndex)
  130. {
  131. return foreFingerDetection.getForeFingerPosition3D(handIndex);
  132. }
  133. public List<Vector> getHandPoints()
  134. {
  135. return foreFingerDetection.getHandPoints();
  136. }
  137. public Palm getPalm(uint handIndex)
  138. {
  139. return palmDetection.getPalm(handIndex);
  140. }
  141. // TODO
  142. public void createVertexArray(IntPtr vertexBuffer)
  143. {
  144. int width = depthImage.getWidth();
  145. int height = depthImage.getHeight();
  146. int confidenceThreshold = inputProvider.getConfidenceThreshold();
  147. int index = 0;
  148. for (int x = 0; x < width; x++)
  149. {
  150. for (int y = 0; y < height; y++)
  151. {
  152. if (confidenceImage.getConfidence(x, y) > confidenceThreshold)
  153. {
  154. int depth = depthImage.getDepth(x, y);
  155. Color c = getColor(x, y);
  156. create3DVertexFrom2D(x, y, depth, c, index, vertexBuffer);
  157. index++;
  158. }
  159. }
  160. }
  161. }
  162. public Vector pixel2VertexPosition(Vector pixelPosition)
  163. {
  164. int width = depthImage.getWidth();
  165. int height = depthImage.getHeight();
  166. float convertedDepth = pixelPosition[2] / 1000f; // mm into m
  167. float u = (pixelPosition[0] / (float)width - 0.5f) * 2f;
  168. float v = ((1 - pixelPosition[1] / (float)height) - 0.5f) * 2f;
  169. float relX = (u * maxU);
  170. float relY = (v * maxV);
  171. Vector result = new DenseVector(3);
  172. result[2] = convertedDepth / (float)Math.Sqrt(1 + relX * relX + relY * relY);
  173. result[0] = relX * result[2];
  174. result[1] = relY * result[2];
  175. return result;
  176. }
  177. private void create3DVertexFrom2D(float pixelX, float pixelY, int depth, Color c, int index, IntPtr vertexBuffer)
  178. {
  179. Vector pixelPosition = new DenseVector(3);
  180. pixelPosition[0] = pixelX;
  181. pixelPosition[1] = pixelY;
  182. pixelPosition[2] = depth;
  183. Vector vertexPosition = pixel2VertexPosition(pixelPosition);
  184. int i4 = (3 * sizeof(float) + 4 * sizeof(byte)) / sizeof(float) * index;
  185. int i16 = (3 * sizeof(float) + 4 * sizeof(byte)) * index;
  186. unsafe
  187. {
  188. byte* vertexArrayB = (byte*)vertexBuffer.ToPointer();
  189. float* vertexArrayF = (float*)vertexBuffer.ToPointer();
  190. vertexArrayF[i4 + 0] = vertexPosition[0];
  191. vertexArrayF[i4 + 1] = vertexPosition[1];
  192. vertexArrayF[i4 + 2] = -vertexPosition[2];
  193. vertexArrayB[i16 + 12] = c.R;
  194. vertexArrayB[i16 + 13] = c.G;
  195. vertexArrayB[i16 + 14] = c.B;
  196. vertexArrayB[i16 + 15] = c.A;
  197. }
  198. }
  199. }
  200. }