123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- using BBIWARG.Recognition.FingerRecognition;
- using BBIWARG.Recognition.PalmRecognition;
- using BBIWARG.Recognition.Tracking;
- using BBIWARG.Utility;
- using Emgu.CV;
- using Emgu.CV.Structure;
- using System.Collections.Generic;
- namespace BBIWARG.Recognition.HandRecognition
- {
- /// <summary>
- /// Represents a Hand.
- /// </summary>
- public class Hand : TrackableObject
- {
- /// <summary>
- /// the center of gravity of the hand
- /// </summary>
- public Vector2D Centroid { get; private set; }
- /// <summary>
- /// the fingers belonging to the hand
- /// </summary>
- public List<Finger> Fingers { get; private set; }
- /// <summary>
- /// a mask of the hand (0=outside, 1=in hand)
- /// </summary>
- public Image<Gray, byte> Mask { get; private set; }
- /// <summary>
- /// the palm belonging to the hand
- /// </summary>
- public Palm Palm { get; set; }
- /// <summary>
- /// Initializes a new instance of the Hand class.
- /// </summary>
- /// <param name="mask">The mask.</param>
- /// <param name="fingers">The fingers.</param>
- public Hand(Image<Gray, byte> mask, List<Finger> fingers)
- {
- Mask = mask;
- Fingers = fingers;
- foreach (Finger finger in Fingers)
- finger.Hand = this;
- }
- /// <summary>
- /// Extends the mask.
- /// </summary>
- /// <param name="extendMask">the mask of the extension</param>
- public void extendMask(Image<Gray, byte> extendMask)
- {
- Mask = Mask.Or(extendMask);
- }
- /// <summary>
- /// Fills the Hand mask defects caused by overlapping fingers.
- /// </summary>
- /// <param name="otherFingers">list of fingers that don't belong to this hand</param>
- public void fillOverlappingFingers(List<Finger> otherFingers)
- {
- ImageSize imageSize = new ImageSize(Mask.Width, Mask.Height);
- foreach (Finger finger in otherFingers)
- {
- FingerSliceTrail trail = null;
- foreach (FingerSlice slice in finger.SliceTrail.Slices)
- {
- Vector2D direction = slice.Direction;
- Vector2D out1 = slice.Start.moveWithinBound(imageSize, direction.getInverse(), Parameters.FingerContourMargin);
- Vector2D out2 = slice.End.moveWithinBound(imageSize, direction, Parameters.FingerContourMargin);
- if (isInside(out1) && isInside(out2))
- {
- if (trail == null)
- trail = new FingerSliceTrail(slice);
- else
- trail.addSlice(slice);
- }
- }
- if (trail != null)
- Mask.FillConvexPoly(trail.getContour(Parameters.FingerOutMargin).ToArray(), new Gray(1));
- }
- Mask = Mask.Dilate(1);
- }
- /// <summary>
- /// Finds the hands centroid (center of gravity).
- /// </summary>
- public void findCentroid()
- {
- MCvPoint2D64f gravityCenter = Mask.GetMoments(true).GravityCenter;
- Centroid = new Vector2D((float)gravityCenter.x, (float)gravityCenter.y);
- }
- /// <summary>
- /// Checks whether a given point is inside the hand.
- /// </summary>
- /// <param name="point">the point</param>
- /// <returns>whether the point is inside the hand</returns>
- public bool isInside(Vector2D point)
- {
- return Mask.Data[point.IntY, point.IntX, 0] != 0;
- }
- /// <summary>
- /// Merges another Hand to this hand by extending the mask and adding the fingers.
- /// </summary>
- /// <param name="mergeHand">the other hand</param>
- public void mergeWith(Hand mergeHand)
- {
- extendMask(mergeHand.Mask);
- Fingers.AddRange(mergeHand.Fingers);
- foreach (Finger finger in mergeHand.Fingers)
- finger.Hand = this;
- }
- }
- }
|