ForeFingerDetection.cs 3.9 KB

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