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 List slices; private LineSegment2D lineSegment; private Contour contour; private Contour innerContour; private bool lineSegmentUpToDate; private bool contourUpToDate; private bool innerContourUpToDate; 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 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.StartOuter); pointsB.Add(slice.EndOuter); } 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; } } }