Hand.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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 Emgu.CV;
  8. using Emgu.CV.Structure;
  9. using bbiwarg.Recognition.FingerRecognition;
  10. using bbiwarg.Utility;
  11. using bbiwarg.Recognition.Tracking;
  12. using bbiwarg.Recognition.PalmRecognition;
  13. namespace bbiwarg.Recognition.HandRecognition
  14. {
  15. /// <summary>
  16. /// Represents a Hand.
  17. /// </summary>
  18. public class Hand : TrackableObject
  19. {
  20. /// <summary>
  21. /// the center of gravity of the hand
  22. /// </summary>
  23. public Vector2D Centroid { get; private set; }
  24. /// <summary>
  25. /// a mask of the hand (0=outside, 1=in hand)
  26. /// </summary>
  27. public Image<Gray, byte> Mask { get; private set; }
  28. /// <summary>
  29. /// the fingers belonging to the hand
  30. /// </summary>
  31. public List<Finger> Fingers { get; private set; }
  32. /// <summary>
  33. /// the palm belonging to the hand
  34. /// </summary>
  35. public Palm Palm { get; set; }
  36. /// <summary>
  37. /// Initializes a new instance of the Hand class.
  38. /// </summary>
  39. /// <param name="mask">The mask.</param>
  40. /// <param name="fingers">The fingers.</param>
  41. public Hand(Image<Gray, byte> mask, List<Finger> fingers)
  42. {
  43. Mask = mask;
  44. Fingers = fingers;
  45. foreach (Finger finger in Fingers)
  46. finger.Hand = this;
  47. }
  48. /// <summary>
  49. /// Checks wether a given point is inside the hand.
  50. /// </summary>
  51. /// <param name="point">the point</param>
  52. /// <returns>wether the point is inside the hand</returns>
  53. public bool isInside(Vector2D point)
  54. {
  55. return (Mask.Data[point.IntY, point.IntX, 0] != 0);
  56. }
  57. /// <summary>
  58. /// Merges another Hand to this hand by extending the mask and adding the fingers.
  59. /// </summary>
  60. /// <param name="mergeHand">the other hand</param>
  61. public void mergeWith(Hand mergeHand)
  62. {
  63. extendMask(mergeHand.Mask);
  64. Fingers.AddRange(mergeHand.Fingers);
  65. foreach (Finger finger in mergeHand.Fingers)
  66. finger.Hand = this;
  67. }
  68. /// <summary>
  69. /// Extends the mask.
  70. /// </summary>
  71. /// <param name="extendMask">the mask of the extension</param>
  72. public void extendMask(Image<Gray, byte> extendMask)
  73. {
  74. Mask = Mask.Or(extendMask);
  75. }
  76. /// <summary>
  77. /// Fills the Hand mask defects caused by overlapping fingers.
  78. /// </summary>
  79. /// <param name="otherFingers">list of fingers that don't belong to this hand</param>
  80. public void fillOverlappingFingers(List<Finger> otherFingers)
  81. {
  82. ImageSize imageSize = new ImageSize(Mask.Width, Mask.Height);
  83. foreach (Finger finger in otherFingers)
  84. {
  85. FingerSliceTrail trail = null;
  86. foreach (FingerSlice slice in finger.SliceTrail.Slices)
  87. {
  88. Vector2D direction = slice.Direction;
  89. Vector2D out1 = slice.Start.moveWithinBound(imageSize, direction.getInverse(), Parameters.FingerContourMargin);
  90. Vector2D out2 = slice.End.moveWithinBound(imageSize, direction, Parameters.FingerContourMargin);
  91. if (isInside(out1) && isInside(out2))
  92. {
  93. if (trail == null)
  94. trail = new FingerSliceTrail(slice);
  95. else
  96. trail.addSlice(slice);
  97. }
  98. }
  99. if (trail != null)
  100. Mask.FillConvexPoly(trail.getContour(Parameters.FingerOutMargin).ToArray(), new Gray(1));
  101. }
  102. Mask = Mask.Dilate(1);
  103. }
  104. /// <summary>
  105. /// Finds the hands centroid (center of gravity).
  106. /// </summary>
  107. public void findCentroid()
  108. {
  109. MCvPoint2D64f gravityCenter = Mask.GetMoments(true).GravityCenter;
  110. Centroid = new Vector2D((float)gravityCenter.x, (float)gravityCenter.y);
  111. }
  112. }
  113. }