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 contour; private Contour innerContour; private Contour outerContour; private bool lineSegmentUpToDate; private bool contourUpToDate; private bool innerContourUpToDate; private bool outerContourUpToDate; public List 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 Contour { get { if (!contourUpToDate) updateContour(); return contour; } } public Contour InnerContour { get { if (!innerContourUpToDate) updateInnerContour(); return innerContour; } } public Contour OuterContour { get { if (!outerContourUpToDate) updateOuterContour(); return outerContour; } } public FingerSliceTrail(FingerSlice slice) { Slices = new List(); addSlice(slice); lineSegmentUpToDate = false; contourUpToDate = false; } public void addSlice(FingerSlice slice) { Slices.Add(slice); lineSegmentUpToDate = false; contourUpToDate = false; } public Vector2D getStartDirection() { int innerStartIndex = Math.Min(NumSlices, Constants.FingerNumSlicesForRelativeDirection); return (StartSlice.Mid - Slices[innerStartIndex].Mid).normalize(); } public Vector2D getEndDirection() { int innerEndIndex = Math.Max(0, NumSlices - Constants.FingerNumSlicesForRelativeDirection); return (EndSlice.Mid - Slices[innerEndIndex].Mid).normalize(); } public void removeFirstSlices(int numSlices) { Slices.RemoveRange(0, numSlices); lineSegmentUpToDate = false; contourUpToDate = false; } public void reverse() { Slices.Reverse(); lineSegmentUpToDate = false; contourUpToDate = false; } private void updateLineSegment() { lineSegment = new LineSegment2D(EndSlice.Mid, StartSlice.Mid); lineSegmentUpToDate = true; } private void updateContour() { List pointsA = new List(); List pointsB = new List(); foreach (FingerSlice slice in Slices) { pointsA.Add(slice.ContourStart); pointsB.Add(slice.ContourEnd); } pointsA.Reverse(); pointsA.AddRange(pointsB); contour = new Contour(new MemStorage()); foreach (Point p in pointsA) { contour.Push(p); } contourUpToDate = true; } private void updateInnerContour() { List pointsA = new List(); List pointsB = new List(); foreach (FingerSlice slice in Slices) { pointsA.Add(slice.Start); pointsB.Add(slice.End); } pointsA.Reverse(); pointsA.AddRange(pointsB); innerContour = new Contour(new MemStorage()); foreach (Point p in pointsA) { innerContour.Push(p); } innerContourUpToDate = true; } private void updateOuterContour() { List pointsA = new List(); List pointsB = new List(); foreach (FingerSlice slice in Slices) { pointsA.Add(slice.OutStart); pointsB.Add(slice.OutEnd); } pointsA.Reverse(); pointsA.AddRange(pointsB); outerContour = new Contour(new MemStorage()); foreach (Point p in pointsA) { outerContour.Push(p); } outerContourUpToDate = true; } } }