ForeFingerDetection.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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. return videoHandle.pixel2VertexPosition(foreFingerPosition);
  58. }
  59. private void checkPoint(Vector point)
  60. {
  61. Vector distanceVector = new DenseVector(3);
  62. videoHandle.pixel2VertexPosition(palmPosition).Subtract(videoHandle.pixel2VertexPosition(point), distanceVector);
  63. float currentPointDistance = distanceVector.Norm(2);
  64. if (currentPointDistance >= foreFingerDistance)
  65. {
  66. foreFingerPosition = point;
  67. foreFingerDistance = currentPointDistance;
  68. }
  69. addNeighbours(point);
  70. }
  71. private void addNeighbours(Vector point)
  72. {
  73. Vector currentPoint;
  74. int x_start = -(int)Math.Min(TOLERANCE_2D, point[0]);
  75. for (int y = -(int)Math.Min(TOLERANCE_2D, point[1]); y <= TOLERANCE_2D && point[1] + y < pixelHeight; y++)
  76. {
  77. for (int x = x_start; x <= TOLERANCE_2D && point[0] + x < pixelWidth; x++)
  78. {
  79. currentPoint = new DenseVector(3);
  80. currentPoint[0] = point[0] + x;
  81. currentPoint[1] = point[1] + y;
  82. currentPoint[2] = videoHandle.getDepth((int)currentPoint[0], (int)currentPoint[1]);
  83. if (point == palmPosition || (Math.Abs(currentPoint[2] - point[2]) <= TOLERANCE_Z && point[1] <= palmPosition[1] && !seenPoints.Contains(currentPoint)))
  84. {
  85. points.Add(currentPoint);
  86. seenPoints.Add(currentPoint);
  87. }
  88. }
  89. }
  90. }
  91. public List<Vector> getHandPoints()
  92. {
  93. return points;
  94. }
  95. }
  96. }