123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using bbiwarg.Utility;
- using Emgu.CV;
- namespace bbiwarg.Recognition.FingerRecognition
- {
- class FingerSliceTrail
- {
- private LineSegment2D lineSegment;
- private Contour<Point> contour;
- private Contour<Point> innerContour;
- private Contour<Point> outerContour;
- private Vector2D fittedDirection;
- private bool lineSegmentUpToDate;
- private bool contourUpToDate;
- private bool innerContourUpToDate;
- private bool outerContourUpToDate;
- private bool fittedDirectionUpToDate;
- public List<FingerSlice> Slices { get; private set; }
- public FingerSlice StartSlice { get { return Slices[0]; } }
- public FingerSlice MidSlice { get { return Slices[NumSlices / 2]; } }
- public FingerSlice EndSlice { get { return Slices[Slices.Count - 1]; } }
- public FingerSlice this[int index] { get { return Slices[index]; } }
- public int NumSlices { get { return Slices.Count; } }
- public LineSegment2D LineSegment { get { if (!lineSegmentUpToDate) updateLineSegment(); return lineSegment; } }
- public Contour<Point> Contour { get { if (!contourUpToDate) updateContour(); return contour; } }
- public Contour<Point> InnerContour { get { if (!innerContourUpToDate) updateInnerContour(); return innerContour; } }
- public Contour<Point> OuterContour { get { if (!outerContourUpToDate) updateOuterContour(); return outerContour; } }
- public Vector2D FittedDirection { get { if (!fittedDirectionUpToDate) updateFittedDirection(); return fittedDirection; } }
- public FingerSliceTrail(FingerSlice slice)
- {
- Slices = new List<FingerSlice>();
- addSlice(slice);
- lineSegmentUpToDate = false;
- contourUpToDate = false;
- fittedDirectionUpToDate = false;
- }
- public void addSlice(FingerSlice slice)
- {
- Slices.Add(slice);
- lineSegmentUpToDate = false;
- contourUpToDate = false;
- fittedDirectionUpToDate = false;
- }
- public Vector2D getStartDirection()
- {
- int innerStartIndex = Math.Min(NumSlices, Parameters.FingerNumSlicesForRelativeDirection);
- return (StartSlice.Mid - Slices[innerStartIndex].Mid).normalize();
- }
- public Vector2D getEndDirection()
- {
- int innerEndIndex = Math.Max(0, NumSlices - Parameters.FingerNumSlicesForRelativeDirection);
- return (EndSlice.Mid - Slices[innerEndIndex].Mid).normalize();
- }
- public void removeFirstSlices(int numSlices)
- {
- Slices.RemoveRange(0, numSlices);
- lineSegmentUpToDate = false;
- contourUpToDate = false;
- fittedDirectionUpToDate = false;
- }
- public void reverse()
- {
- Slices.Reverse();
- lineSegmentUpToDate = false;
- contourUpToDate = false;
- fittedDirectionUpToDate = false;
- }
- private void updateLineSegment()
- {
-
- float length_2 = 0.5f * (EndSlice.Mid.getDistanceTo(StartSlice.Mid));
- Vector2D p1 = MidSlice.Mid + length_2 * FittedDirection;
- Vector2D p2 = MidSlice.Mid - length_2 * FittedDirection;
- lineSegment = new LineSegment2D(p1, p2);
- lineSegmentUpToDate = true;
- }
- private void updateFittedDirection()
- {
- List<PointF> midPoints = new List<PointF>();
- foreach (FingerSlice slice in Slices)
- midPoints.Add(slice.Mid);
- PointF pointOnLine, direction;
- PointCollection.Line2DFitting(midPoints.ToArray(), Emgu.CV.CvEnum.DIST_TYPE.CV_DIST_FAIR, out direction, out pointOnLine);
- fittedDirection = new Vector2D(direction).normalize().getInverse();
- fittedDirectionUpToDate = true;
- }
- private void updateContour()
- {
- List<Point> pointsA = new List<Point>();
- List<Point> pointsB = new List<Point>();
- foreach (FingerSlice slice in Slices)
- {
- pointsA.Add(slice.ContourStart);
- pointsB.Add(slice.ContourEnd);
- }
- pointsA.Reverse();
- pointsA.AddRange(pointsB);
- contour = new Contour<Point>(new MemStorage());
- foreach (Point p in pointsA)
- {
- contour.Push(p);
- }
- contourUpToDate = true;
- }
- private void updateInnerContour()
- {
- List<Point> pointsA = new List<Point>();
- List<Point> pointsB = new List<Point>();
- foreach (FingerSlice slice in Slices)
- {
- pointsA.Add(slice.Start);
- pointsB.Add(slice.End);
- }
- pointsA.Reverse();
- pointsA.AddRange(pointsB);
- innerContour = new Contour<Point>(new MemStorage());
- foreach (Point p in pointsA)
- {
- innerContour.Push(p);
- }
- innerContourUpToDate = true;
- }
- private void updateOuterContour()
- {
- List<Point> pointsA = new List<Point>();
- List<Point> pointsB = new List<Point>();
- foreach (FingerSlice slice in Slices)
- {
- pointsA.Add(slice.OutStart);
- pointsB.Add(slice.OutEnd);
- }
- pointsA.Reverse();
- pointsA.AddRange(pointsB);
- outerContour = new Contour<Point>(new MemStorage());
- foreach (Point p in pointsA)
- {
- outerContour.Push(p);
- }
- outerContourUpToDate = true;
- }
- }
- }
|