ForeFingerDetection.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using MathNet.Numerics.LinearAlgebra.Single;
  7. using System.Drawing;
  8. namespace bbiwarg.DataSource
  9. {
  10. class ForeFingerDetection
  11. {
  12. /*
  13. * Returns the forefinger's position
  14. * all fingers (except der forefinger) have to be inactive
  15. * params:
  16. * handIndex: which hand's forefinger's position
  17. */
  18. public const int TOLERANCE_Z = 5;
  19. public const int TOLERANCE_2D = 7;
  20. private IInputProvider inputProvider;
  21. private IVideoHandle videoHandle;
  22. private List<Vector> points;
  23. private HashSet<Vector> seenPoints;
  24. private Vector palmPosition;
  25. private Vector foreFingerPosition;
  26. private float foreFingerDistance;
  27. private float lowestY;
  28. private float highestZ;
  29. public ForeFingerDetection(IInputProvider inputProvider, IVideoHandle videoHandle)
  30. {
  31. this.inputProvider = inputProvider;
  32. this.videoHandle = videoHandle;
  33. }
  34. public Vector getForeFingerPosition3D(uint handIndex)
  35. {
  36. Vector palmPosition2D = inputProvider.getPalmPosition2D(handIndex);
  37. palmPosition = new DenseVector(3);
  38. palmPosition[0] = palmPosition2D[0];
  39. palmPosition[1] = palmPosition2D[1];
  40. palmPosition[2] = videoHandle.getDepth((int)palmPosition[0], (int)palmPosition[1]);
  41. points = new List<Vector>();
  42. seenPoints = new HashSet<Vector>();
  43. foreFingerPosition = palmPosition;
  44. foreFingerDistance = 0;
  45. lowestY = palmPosition[1];
  46. highestZ = palmPosition[2];
  47. points.Add(palmPosition);
  48. seenPoints.Add(palmPosition);
  49. for (int i = 0; i < points.Count(); i++)
  50. {
  51. checkPoint(points[i]);
  52. }
  53. return videoHandle.pixel2VertexPosition(foreFingerPosition);
  54. }
  55. private void checkPoint(Vector point)
  56. {
  57. bool isLowestY = point[1] <= lowestY;
  58. bool isHighestZ = point[2] >= highestZ;
  59. if (isLowestY || isHighestZ)
  60. {
  61. if (isLowestY)
  62. {
  63. if (lowestY == foreFingerPosition[1])
  64. foreFingerDistance = 0;
  65. lowestY = point[1];
  66. }
  67. if (isHighestZ)
  68. {
  69. if (highestZ == foreFingerPosition[2])
  70. foreFingerDistance = 0;
  71. highestZ = point[2];
  72. }
  73. Vector distanceVector = new DenseVector(3);
  74. videoHandle.pixel2VertexPosition(palmPosition).Subtract(videoHandle.pixel2VertexPosition(point), distanceVector);
  75. //palmPosition.Subtract(point, distanceVector);
  76. float currentPointDistance = distanceVector.Norm(2);
  77. if (currentPointDistance >= foreFingerDistance)
  78. {
  79. foreFingerPosition = point;
  80. foreFingerDistance = currentPointDistance;
  81. addNeighbours(point);
  82. }
  83. }
  84. }
  85. private void addNeighbours(Vector point)
  86. {
  87. Vector currentPoint;
  88. for (int y = -(int)Math.Min(TOLERANCE_2D, point[1]); y <= TOLERANCE_2D && point[1] + y < videoHandle.getHeight(); y++)
  89. {
  90. for (int x = -(int)Math.Min(TOLERANCE_2D, point[0]); x <= TOLERANCE_2D && point[0] + x < videoHandle.getWidth(); x++)
  91. {
  92. currentPoint = new DenseVector(3);
  93. currentPoint[0] = point[0] + x;
  94. currentPoint[1] = point[1] + y;
  95. currentPoint[2] = videoHandle.getDepth((int)currentPoint[0], (int)currentPoint[1]);
  96. if (Math.Abs(currentPoint[2] - point[2]) <= TOLERANCE_Z && !seenPoints.Contains(currentPoint))
  97. {
  98. points.Add(currentPoint);
  99. seenPoints.Add(currentPoint);
  100. }
  101. }
  102. }
  103. }
  104. }
  105. }