static bool IsWithinGapLimits(SkeletonMinutia end1, SkeletonMinutia end2) { const int ruptureSize = 5; const int gapSize = 20; const byte gapAngle = 32; int distanceSq = (end1.Position - end2.Position).SqLength; if (distanceSq <= MathEx.Sq(ruptureSize)) { return(true); } if (distanceSq > MathEx.Sq(gapSize)) { return(false); } byte gapDirection = Angle.AtanB(end1.Position, end2.Position); byte direction1 = Angle.AtanB(end1.Position, GetAngleSampleForGapRemoval(end1)); if (Angle.Distance(direction1, Angle.Opposite(gapDirection)) > gapAngle) { return(false); } byte direction2 = Angle.AtanB(end2.Position, GetAngleSampleForGapRemoval(end2)); if (Angle.Distance(direction2, gapDirection) > gapAngle) { return(false); } return(true); }
static bool IsWithinGapLimits(SkeletonMinutia end1, SkeletonMinutia end2) { int distanceSq = (end1.Position - end2.Position).LengthSq; if (distanceSq <= Integers.Sq(Parameters.MaxRuptureSize)) { return(true); } if (distanceSq > Integers.Sq(Parameters.MaxGapSize)) { return(false); } double gapDirection = DoubleAngle.Atan(end1.Position, end2.Position); double direction1 = DoubleAngle.Atan(end1.Position, AngleSampleForGapRemoval(end1)); if (DoubleAngle.Distance(direction1, DoubleAngle.Opposite(gapDirection)) > Parameters.MaxGapAngle) { return(false); } double direction2 = DoubleAngle.Atan(end2.Position, AngleSampleForGapRemoval(end2)); if (DoubleAngle.Distance(direction2, gapDirection) > Parameters.MaxGapAngle) { return(false); } return(true); }
void RemovePores() { const int maxArmLength = 41; foreach (SkeletonMinutia minutia in Minutiae) { if (minutia.Ridges.Count == 3) { for (int exit = 0; exit < 3; ++exit) { SkeletonRidge exitRidge = minutia.Ridges[exit]; SkeletonRidge arm1 = minutia.Ridges[(exit + 1) % 3]; SkeletonRidge arm2 = minutia.Ridges[(exit + 2) % 3]; if (arm1.End == arm2.End && exitRidge.End != arm1.End && arm1.End != minutia && exitRidge.End != minutia) { SkeletonMinutia end = arm1.End; if (end.Ridges.Count == 3 && arm1.Points.Count <= maxArmLength && arm2.Points.Count <= maxArmLength) { arm1.Detach(); arm2.Detach(); SkeletonRidge merged = new SkeletonRidge(); merged.Start = minutia; merged.End = end; foreach (Point point in MathEx.ConstructLine(minutia.Position, end.Position)) { merged.Points.Add(point); } } break; } } } } RemoveKnots(); }
static Point GetAngleSampleForGapRemoval(SkeletonMinutia minutia) { const int angleSampleOffset = 22; SkeletonRidge ridge = minutia.Ridges[0]; if (angleSampleOffset < ridge.Points.Count) return ridge.Points[angleSampleOffset]; else return ridge.End.Position; }
static IntPoint AngleSampleForGapRemoval(SkeletonMinutia minutia) { var ridge = minutia.Ridges[0]; if (Parameters.GapAngleOffset < ridge.Points.Count) { return(ridge.Points[Parameters.GapAngleOffset]); } else { return(ridge.End.Position); } }
static Point GetAngleSampleForGapRemoval(SkeletonMinutia minutia) { const int angleSampleOffset = 22; SkeletonRidge ridge = minutia.Ridges[0]; if (angleSampleOffset < ridge.Points.Count) { return(ridge.Points[angleSampleOffset]); } else { return(ridge.End.Position); } }
Dictionary <IntPoint, SkeletonMinutia> MinutiaCenters(Dictionary <IntPoint, List <IntPoint> > linking) { var centers = new Dictionary <IntPoint, SkeletonMinutia>(); foreach (var currentPos in linking.Keys) { var linkedMinutiae = linking[currentPos]; var primaryPos = linkedMinutiae[0]; if (!centers.ContainsKey(primaryPos)) { var sum = IntPoint.Zero; foreach (var linkedPos in linkedMinutiae) { sum += linkedPos; } var center = new IntPoint(sum.X / linkedMinutiae.Count, sum.Y / linkedMinutiae.Count); var minutia = new SkeletonMinutia(center); AddMinutia(minutia); centers[primaryPos] = minutia; } centers[currentPos] = centers[primaryPos]; } return(centers); }
Dictionary <Point, SkeletonMinutia> ComputeMinutiaCenters(Dictionary <Point, List <Point> > linking) { Dictionary <Point, SkeletonMinutia> centers = new Dictionary <Point, SkeletonMinutia>(); foreach (Point currentPos in linking.Keys) { List <Point> linkedMinutiae = linking[currentPos]; Point primaryPos = linkedMinutiae[0]; if (!centers.ContainsKey(primaryPos)) { Point sum = new Point(); foreach (Point linkedPos in linkedMinutiae) { sum += linkedPos; } Point center = new Point(sum.X / linkedMinutiae.Count, sum.Y / linkedMinutiae.Count); SkeletonMinutia minutia = new SkeletonMinutia(center); AddMinutia(minutia); centers[primaryPos] = minutia; } centers[currentPos] = centers[primaryPos]; } return(centers); }
public void RemoveMinutia(SkeletonMinutia minutia) { Minutiae.Remove(minutia); }
public void AddMinutia(SkeletonMinutia minutia) { Minutiae.Add(minutia); }
public void Detach() { Start = null; End = null; }
Dictionary<Point, SkeletonMinutia> ComputeMinutiaCenters(Dictionary<Point, List<Point>> linking) { Dictionary<Point, SkeletonMinutia> centers = new Dictionary<Point, SkeletonMinutia>(); foreach (Point currentPos in linking.Keys) { List<Point> linkedMinutiae = linking[currentPos]; Point primaryPos = linkedMinutiae[0]; if (!centers.ContainsKey(primaryPos)) { Point sum = new Point(); foreach (Point linkedPos in linkedMinutiae) sum += linkedPos; Point center = new Point(sum.X / linkedMinutiae.Count, sum.Y / linkedMinutiae.Count); SkeletonMinutia minutia = new SkeletonMinutia(center); AddMinutia(minutia); centers[primaryPos] = minutia; } centers[currentPos] = centers[primaryPos]; } return centers; }
static bool IsWithinGapLimits(SkeletonMinutia end1, SkeletonMinutia end2) { const int ruptureSize = 5; const int gapSize = 20; const byte gapAngle = 32; int distanceSq = (end1.Position - end2.Position).SqLength; if (distanceSq <= MathEx.Sq(ruptureSize)) return true; if (distanceSq > MathEx.Sq(gapSize)) return false; byte gapDirection = Angle.AtanB(end1.Position, end2.Position); byte direction1 = Angle.AtanB(end1.Position, GetAngleSampleForGapRemoval(end1)); if (Angle.Distance(direction1, Angle.Opposite(gapDirection)) > gapAngle) return false; byte direction2 = Angle.AtanB(end2.Position, GetAngleSampleForGapRemoval(end2)); if (Angle.Distance(direction2, gapDirection) > gapAngle) return false; return true; }