ForeFingerDetection.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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 = 3;
  19. public const int TOLERANCE_2D = 3;
  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 int pixelWidth;
  28. private int pixelHeight;
  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. pixelWidth = videoHandle.getWidth();
  37. pixelHeight = videoHandle.getHeight();
  38. Vector palmPosition2D = inputProvider.getPalmPosition2D(handIndex);
  39. palmPosition = new DenseVector(3);
  40. palmPosition[0] = palmPosition2D[0];
  41. palmPosition[1] = palmPosition2D[1];
  42. palmPosition[2] = videoHandle.getDepth((int)palmPosition[0], (int)palmPosition[1]);
  43. points = new List<Vector>();
  44. seenPoints = new HashSet<Vector>();
  45. foreFingerPosition = palmPosition;
  46. foreFingerDistance = 0;
  47. points.Add(palmPosition);
  48. seenPoints.Add(palmPosition);
  49. for (int i = 0; i < points.Count(); i++)
  50. {
  51. checkPoint(points[i]);
  52. }
  53. if (points.Count() <= 10)
  54. {
  55. Console.WriteLine(palmPosition[2]);
  56. }
  57. if (seenPoints.Count() <= 100)
  58. {
  59. }
  60. return videoHandle.pixel2VertexPosition(foreFingerPosition);
  61. }
  62. private void checkPoint(Vector point)
  63. {
  64. Vector distanceVector = new DenseVector(3);
  65. videoHandle.pixel2VertexPosition(palmPosition).Subtract(videoHandle.pixel2VertexPosition(point), distanceVector);
  66. float currentPointDistance = distanceVector.Norm(2);
  67. if (currentPointDistance >= foreFingerDistance)
  68. {
  69. foreFingerPosition = point;
  70. foreFingerDistance = currentPointDistance;
  71. }
  72. addNeighbours(point);
  73. }
  74. private void addNeighbours(Vector point)
  75. {
  76. Vector currentPoint;
  77. int x_start = -(int)Math.Min(TOLERANCE_2D, point[0]);
  78. for (int y = -(int)Math.Min(TOLERANCE_2D, point[1]); y <= TOLERANCE_2D && point[1] + y < pixelHeight; y++)
  79. {
  80. for (int x = x_start; x <= TOLERANCE_2D && point[0] + x < pixelWidth; x++)
  81. {
  82. currentPoint = new DenseVector(3);
  83. currentPoint[0] = point[0] + x;
  84. currentPoint[1] = point[1] + y;
  85. currentPoint[2] = videoHandle.getDepth((int)currentPoint[0], (int)currentPoint[1]);
  86. if ((!seenPoints.Contains(currentPoint) && point[1] <= palmPosition[1] && Math.Abs(currentPoint[2] - point[2]) <= TOLERANCE_Z)
  87. || point == palmPosition)
  88. {
  89. points.Add(currentPoint);
  90. }
  91. seenPoints.Add(currentPoint);
  92. }
  93. }
  94. }
  95. public List<Vector> getHandPoints()
  96. {
  97. return points;
  98. }
  99. }
  100. }