Beispiel #1
0
        FingerprintTemplate(MutableTemplate mutable)
        {
            Size = mutable.Size;
            var minutiae =
                from m in mutable.Minutiae
                orderby((m.Position.X * Prime) + m.Position.Y) * Prime, m.Position.X, m.Position.Y, m.Direction, m.Type
                select new ImmutableMinutia(m);

            Minutiae = minutiae.ToArray();
            // https://sourceafis.machinezoo.com/transparency/shuffled-minutiae
            FingerprintTransparency.Current.Log("shuffled-minutiae", () => Mutable());
            Edges = NeighborEdge.BuildTable(Minutiae);
        }
        static List <MatchingPair> FindMatchingPairs(NeighborEdge[] probeStar, NeighborEdge[] candidateStar)
        {
            byte  complementaryAngleError = Angle.Complementary(FingerprintMatcher.MaxAngleError);
            var   results = new List <MatchingPair>();
            Range range   = new Range();

            for (int candidateIndex = 0; candidateIndex < candidateStar.Length; ++candidateIndex)
            {
                NeighborEdge candidateEdge = candidateStar[candidateIndex];

                while (range.Begin < probeStar.Length && probeStar[range.Begin].Edge.Length < candidateEdge.Edge.Length - FingerprintMatcher.MaxDistanceError)
                {
                    ++range.Begin;
                }
                if (range.End < range.Begin)
                {
                    range.End = range.Begin;
                }
                while (range.End < probeStar.Length && probeStar[range.End].Edge.Length <= candidateEdge.Edge.Length + FingerprintMatcher.MaxDistanceError)
                {
                    ++range.End;
                }

                for (int probeIndex = range.Begin; probeIndex < range.End; ++probeIndex)
                {
                    var  probeEdge     = probeStar[probeIndex];
                    byte referenceDiff = Angle.Difference(probeEdge.Edge.ReferenceAngle, candidateEdge.Edge.ReferenceAngle);
                    if (referenceDiff <= FingerprintMatcher.MaxAngleError || referenceDiff >= complementaryAngleError)
                    {
                        byte neighborDiff = Angle.Difference(probeEdge.Edge.NeighborAngle, candidateEdge.Edge.NeighborAngle);
                        if (neighborDiff <= FingerprintMatcher.MaxAngleError || neighborDiff >= complementaryAngleError)
                        {
                            results.Add(new MatchingPair()
                            {
                                Pair = new MinutiaPair()
                                {
                                    Probe     = probeEdge.Neighbor,
                                    Candidate = candidateEdge.Neighbor
                                },
                                Distance = candidateEdge.Edge.Length
                            });
                        }
                    }
                }
            }
            return(results);
        }
        public static NeighborEdge[][] BuildTable(ImmutableMinutia[] minutiae)
        {
            var edges          = new NeighborEdge[minutiae.Length][];
            var star           = new List <NeighborEdge>();
            var allSqDistances = new int[minutiae.Length];

            for (int reference = 0; reference < edges.Length; ++reference)
            {
                var referencePosition = minutiae[reference].Position;
                int maxSqDistance     = Int32.MaxValue;
                if (minutiae.Length - 1 > Parameters.EdgeTableNeighbors)
                {
                    for (int neighbor = 0; neighbor < minutiae.Length; ++neighbor)
                    {
                        allSqDistances[neighbor] = (referencePosition - minutiae[neighbor].Position).LengthSq;
                    }
                    Array.Sort(allSqDistances);
                    maxSqDistance = allSqDistances[Parameters.EdgeTableNeighbors];
                }
                for (int neighbor = 0; neighbor < minutiae.Length; ++neighbor)
                {
                    if (neighbor != reference && (referencePosition - minutiae[neighbor].Position).LengthSq <= maxSqDistance)
                    {
                        star.Add(new NeighborEdge(minutiae, reference, neighbor));
                    }
                }
                star.Sort((a, b) =>
                {
                    int lengthCmp = a.Length.CompareTo(b.Length);
                    if (lengthCmp != 0)
                    {
                        return(lengthCmp);
                    }
                    return(a.Neighbor.CompareTo(b.Neighbor));
                });
                while (star.Count > Parameters.EdgeTableNeighbors)
                {
                    star.RemoveAt(star.Count - 1);
                }
                edges[reference] = star.ToArray();
                star.Clear();
            }
            // https://sourceafis.machinezoo.com/transparency/edge-table
            FingerprintTransparency.Current.Log("edge-table", edges);
            return(edges);
        }
        void BuildEdgeTable()
        {
            const int maxDistance  = 490;
            const int maxNeighbors = 9;

            EdgeTable = new NeighborEdge[Minutiae.Count][];
            var edges          = new List <NeighborEdge>();
            var allSqDistances = new int[Minutiae.Count];

            for (int reference = 0; reference < EdgeTable.Length; ++reference)
            {
                Point referencePosition = Minutiae[reference].Position;
                int   sqMaxDistance     = MathEx.Sq(maxDistance);
                if (Minutiae.Count - 1 > maxNeighbors)
                {
                    for (int neighbor = 0; neighbor < Minutiae.Count; ++neighbor)
                    {
                        allSqDistances[neighbor] = (referencePosition - Minutiae[neighbor].Position).SqLength;
                    }
                    Array.Sort(allSqDistances);
                    sqMaxDistance = allSqDistances[maxNeighbors];
                }
                for (int neighbor = 0; neighbor < Minutiae.Count; ++neighbor)
                {
                    if (neighbor != reference && (referencePosition - Minutiae[neighbor].Position).SqLength <= sqMaxDistance)
                    {
                        NeighborEdge record = new NeighborEdge();
                        record.Edge     = new EdgeShape(this, reference, neighbor);
                        record.Neighbor = neighbor;
                        edges.Add(record);
                    }
                }

                edges.Sort(NeighborEdgeComparer.Instance);
                if (edges.Count > maxNeighbors)
                {
                    edges.RemoveRange(maxNeighbors, edges.Count - maxNeighbors);
                }
                EdgeTable[reference] = edges.ToArray();
                edges.Clear();
            }
        }
Beispiel #5
0
        static List<MatchingPair> FindMatchingPairs(NeighborEdge[] probeStar, NeighborEdge[] candidateStar)
        {
            byte complementaryAngleError = Angle.Complementary(FingerprintMatcher.MaxAngleError);
            var results = new List<MatchingPair>();
            Range range = new Range();

            for (int candidateIndex = 0; candidateIndex < candidateStar.Length; ++candidateIndex)
            {
                NeighborEdge candidateEdge = candidateStar[candidateIndex];

                while (range.Begin < probeStar.Length && probeStar[range.Begin].Edge.Length < candidateEdge.Edge.Length - FingerprintMatcher.MaxDistanceError)
                    ++range.Begin;
                if (range.End < range.Begin)
                    range.End = range.Begin;
                while (range.End < probeStar.Length && probeStar[range.End].Edge.Length <= candidateEdge.Edge.Length + FingerprintMatcher.MaxDistanceError)
                    ++range.End;

                for (int probeIndex = range.Begin; probeIndex < range.End; ++probeIndex)
                {
                    var probeEdge = probeStar[probeIndex];
                    byte referenceDiff = Angle.Difference(probeEdge.Edge.ReferenceAngle, candidateEdge.Edge.ReferenceAngle);
                    if (referenceDiff <= FingerprintMatcher.MaxAngleError || referenceDiff >= complementaryAngleError)
                    {
                        byte neighborDiff = Angle.Difference(probeEdge.Edge.NeighborAngle, candidateEdge.Edge.NeighborAngle);
                        if (neighborDiff <= FingerprintMatcher.MaxAngleError || neighborDiff >= complementaryAngleError)
                            results.Add(new MatchingPair()
                            {
                                Pair = new MinutiaPair()
                                {
                                    Probe = probeEdge.Neighbor,
                                    Candidate = candidateEdge.Neighbor
                                },
                                Distance = candidateEdge.Edge.Length
                            });
                    }
                }
            }
            return results;
        }