VideoHandle.cs 6.5 KB

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