Hand.cs 4.1 KB

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