Finger.cs 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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 bbiwarg.Images;
  8. using bbiwarg.Utility;
  9. using Emgu.CV;
  10. namespace bbiwarg.Detectors.FingerDetection
  11. {
  12. class Finger
  13. {
  14. public Vector2D TipPoint { get { return SliceTrail.Start.Mid; } }
  15. public Vector2D HandPoint { get { return SliceTrail.End.Mid; } }
  16. public LineSegment2D LineSegment { get { return SliceTrail.LineSegment; } }
  17. public FingerSliceTrail SliceTrail { get; private set; }
  18. public Finger(FingerSliceTrail sliceTrail)
  19. {
  20. //check direction
  21. if (sliceTrail.Start.Length > sliceTrail.End.Length)
  22. sliceTrail.Slices.Reverse();
  23. SliceTrail = sliceTrail;
  24. }
  25. public Contour<Point> getContour()
  26. {
  27. List<Point> pointsA = new List<Point>();
  28. List<Point> pointsB = new List<Point>();
  29. foreach (FingerSlice slice in SliceTrail.Slices)
  30. {
  31. Vector2D direction = (slice.End - slice.Start).normalize();
  32. pointsA.Add(slice.Start - Constants.FingerContourMargin * direction);
  33. pointsB.Add(slice.End + Constants.FingerContourMargin * direction);
  34. }
  35. pointsA.Reverse();
  36. pointsA.AddRange(pointsB);
  37. Contour<Point> contour = new Contour<Point>(new MemStorage());
  38. foreach (Point p in pointsA)
  39. {
  40. contour.Push(p);
  41. }
  42. return contour;
  43. }
  44. //TODO: redo (not use similarity but actual distances and angle instead)
  45. public float getSimilarity(Finger compareFinger)
  46. {
  47. LineSegment2D compareLineSegment = compareFinger.LineSegment;
  48. Line2D compareLine = compareLineSegment.Line;
  49. //thresholds
  50. float thresholdMaxAngle = (float)(30 * Math.PI / 180); // 30°
  51. float thresholdMaxParallelDistance = 80;
  52. float thresholdMaxVerticalDistance = 40;
  53. //check angle
  54. float angle = LineSegment.Line.getAngleBetween(compareLine);
  55. float angleSimilarity = Math.Max(1 - angle / thresholdMaxAngle, 0);
  56. //check parallel distance
  57. float parallelDistance = LineSegment.getParallelDistanceTo(compareLineSegment);
  58. float parallelDistanceSimilarity = Math.Max(1 - parallelDistance / thresholdMaxParallelDistance, 0);
  59. //check vertical distance
  60. float verticalDistance = LineSegment.getVerticalDistanceTo(compareLineSegment);
  61. float verticalDistanceSimilarity = Math.Max(1 - verticalDistance / thresholdMaxVerticalDistance, 0);
  62. return (angleSimilarity + parallelDistanceSimilarity + verticalDistanceSimilarity) / 3;
  63. }
  64. }
  65. }