public IEnumerable<MinutiaPair> GetFilteredRoots(ProbeIndex probeIndex, Template candidateTemplate, Predicate<EdgeShape> shapeFilter)
 {
     if (LookupCounter >= MaxEdgeLookups)
         yield break;
     var edgeConstructor = new EdgeConstructor();
     for (int step = 1; step < candidateTemplate.Minutiae.Length; ++step)
         for (int pass = 0; pass < step + 1; ++pass)
             for (int candidateReference = pass; candidateReference < candidateTemplate.Minutiae.Length; candidateReference += step + 1)
             {
                 int candidateNeighbor = (candidateReference + step) % candidateTemplate.Minutiae.Length;
                 var candidateEdge = edgeConstructor.Construct(candidateTemplate, candidateReference, candidateNeighbor);
                 if (shapeFilter(candidateEdge))
                 {
                     for (var match = HashLookup.Select(candidateEdge); match != null; match = HashLookup.Next())
                     {
                         var pair = new MinutiaPair(match.Location.Reference, candidateReference);
                         if (Logger.IsActive)
                             Logger.Log(pair);
                         yield return pair;
                         ++LookupCounter;
                         if (LookupCounter >= MaxEdgeLookups)
                             yield break;
                     }
                 }
             }
 }
 public void BuildIndex(Template probe, ProbeIndex index)
 {
     index.Template = probe;
     index.Edges = ParameterSet.ClonePrototype(EdgeTablePrototype);
     index.Edges.Reset(probe);
     index.EdgeHash = new EdgeHash(probe, EdgeLookup);
 }
 public IEnumerable<MinutiaPair> GetRoots(ProbeIndex probeIndex, Template candidateTemplate)
 {
     LookupCounter = 0;
     HashLookup.Reset(probeIndex.EdgeHash);
     return GetFilteredRoots(probeIndex, candidateTemplate, shape => shape.Length >= MinEdgeLength)
         .Concat(GetFilteredRoots(probeIndex, candidateTemplate, shape => shape.Length < MinEdgeLength));
 }
Exemple #4
0
 public EdgeHash(Template template, EdgeLookup lookup)
 {
     EdgeLookup = lookup;
     var edgeConstructor = new EdgeConstructor();
     for (int referenceMinutia = 0; referenceMinutia < template.Minutiae.Length; ++referenceMinutia)
         for (int neighborMinutia = 0; neighborMinutia < template.Minutiae.Length; ++neighborMinutia)
             if (referenceMinutia != neighborMinutia)
             {
                 var edge = new IndexedEdge()
                 {
                     Shape = edgeConstructor.Construct(template, referenceMinutia, neighborMinutia),
                     Location = new EdgeLocation(referenceMinutia, neighborMinutia)
                 };
                 foreach (var hash in lookup.HashCoverage(edge.Shape))
                 {
                     object value;
                     List<IndexedEdge> list;
                     if (!Hash.TryGetValue(hash, out value))
                         Hash[hash] = edge;
                     else
                     {
                         list = value as List<IndexedEdge>;
                         if (list == null)
                         {
                             Hash[hash] = list = new List<IndexedEdge>(1);
                             list.Add((IndexedEdge)value);
                         }
                         list.Add(edge);
                     }
                 }
             }
 }
Exemple #5
0
 public void SelectProbe(Template probe)
 {
     ProbeIndex = new PairInfo[probe.Minutiae.Length];
     PairList = new PairInfo[probe.Minutiae.Length];
     for (int i = 0; i < PairList.Length; ++i)
         PairList[i] = new PairInfo();
     PairCount = 0;
 }
 public EdgeShape Construct(Template template, int reference, int neighbor)
 {
     PolarPoint polar = Angle.ToPolar(Calc.Difference(template.Minutiae[neighbor].Position, template.Minutiae[reference].Position));
     EdgeShape edge;
     edge.Length = (short)polar.Distance;
     edge.ReferenceAngle = Angle.Difference(template.Minutiae[reference].Direction, polar.Angle);
     edge.NeighborAngle = Angle.Difference(template.Minutiae[neighbor].Direction, Angle.Opposite(polar.Angle));
     return edge;
 }
Exemple #7
0
 public void SelectCandidate(Template candidate)
 {
     if (CandidateIndex == null || CandidateIndex.Length < candidate.Minutiae.Length)
         CandidateIndex = new PairInfo[candidate.Minutiae.Length];
     else
     {
         for (int i = 0; i < CandidateIndex.Length; ++i)
             CandidateIndex[i] = null;
     }
 }
Exemple #8
0
 public PreparedProbe Prepare(Template probe)
 {
     PreparedProbe prepared = new PreparedProbe();
     MinutiaMatcher matcher = DequeueMatcher();
     try
     {
         matcher.BuildIndex(probe, prepared.ProbeIndex);
     }
     finally
     {
         EnqueueMatcher(matcher);
     }
     return prepared;
 }
        public float Match(Template candidate)
        {
            PrepareCandidate(candidate);

            int rootIndex = 0;
            int triangleIndex = 0;
            float bestScore = 0;
            MinutiaPair bestRoot = new MinutiaPair();
            int bestRootIndex = -1;
            foreach (MinutiaPair root in RootSelector.GetRoots(Probe, candidate))
            {
                float score = TryRoot(root, candidate);
                if (score > bestScore)
                {
                    bestScore = score;
                    bestRoot = root;
                    bestRootIndex = rootIndex;
                }
                ++rootIndex;
                if (rootIndex >= MaxTriedRoots)
                    break;
                if (Pairing.Count >= 3)
                {
                    ++triangleIndex;
                    if (triangleIndex >= MaxTriedTriangles)
                        break;
                }
            }
            Logger.Log("Score", bestScore);
            Logger.Log("BestRootIndex", bestRootIndex);
            if (bestScore > 0 && Logger.IsActive)
            {
                Pairing.Reset(bestRoot);
                BuildPairing(candidate);
                Logger.Log("BestRoot", bestRoot);
                Logger.Log("BestPairing", Pairing);
            }
            return bestScore;
        }
Exemple #10
0
        public void Analyze(MinutiaPairing pairing, EdgeLookup lookup, Template probe, Template candidate)
        {
            MaxDistanceError = lookup.MaxDistanceError;
            MaxAngleError = lookup.MaxAngleError;
            var innerDistanceRadius = Convert.ToInt32(DistanceErrorFlatness * MaxDistanceError);
            var innerAngleRadius = Convert.ToInt32(AngleErrorFlatness * MaxAngleError);

            PairCount = pairing.Count;

            EdgeCount = 0;
            SupportedCount = 0;
            CorrectTypeCount = 0;
            DistanceErrorSum = 0;
            AngleErrorSum = 0;

            for (int i = 0; i < PairCount; ++i)
            {
                PairInfo pair = pairing.GetPair(i);
                if (pair.SupportingEdges >= MinSupportingEdges)
                    ++SupportedCount;
                EdgeCount += pair.SupportingEdges + 1;
                if (probe.Minutiae[pair.Pair.Probe].Type == candidate.Minutiae[pair.Pair.Candidate].Type)
                    ++CorrectTypeCount;
                if (i > 0)
                {
                    var probeEdge = EdgeConstructor.Construct(probe, pair.Reference.Probe, pair.Pair.Probe);
                    var candidateEdge = EdgeConstructor.Construct(candidate, pair.Reference.Candidate, pair.Pair.Candidate);
                    DistanceErrorSum += Math.Abs(probeEdge.Length - candidateEdge.Length);
                    AngleErrorSum += Math.Max(innerDistanceRadius, Angle.Distance(probeEdge.ReferenceAngle, candidateEdge.ReferenceAngle));
                    AngleErrorSum += Math.Max(innerAngleRadius, Angle.Distance(probeEdge.NeighborAngle, candidateEdge.NeighborAngle));
                }
            }

            float probeFraction = PairCount / (float)probe.Minutiae.Length;
            float candidateFraction = PairCount / (float)candidate.Minutiae.Length;
            PairFraction = (probeFraction + candidateFraction) / 2;
        }
 void BuildPairing(Template candidate)
 {
     while (true)
     {
         CollectEdges(candidate);
         PairSelector.SkipPaired(Pairing);
         if (PairSelector.Count == 0)
             break;
         Pairing.Add(PairSelector.Dequeue());
     }
     Pairing.Log();
 }
        float TryRoot(MinutiaPair root, Template candidate)
        {
            Pairing.Reset(root);
            BuildPairing(candidate);

            MatchAnalysis.Analyze(Pairing, EdgeLookup, Probe.Template, candidate);
            return MatchScoring.Compute(MatchAnalysis);
        }
 void PrepareCandidate(Template candidate)
 {
     Pairing.SelectCandidate(candidate);
     PairSelector.Clear();
     CandidateEdges.Reset(candidate);
 }
 void CollectEdges(Template candidate)
 {
     var reference = Pairing.LastAdded.Pair;
     var probeNeighbors = Probe.Edges.Table[reference.Probe];
     var candidateNeigbors = CandidateEdges.Table[reference.Candidate];
     var matches = EdgeLookup.FindMatchingPairs(probeNeighbors, candidateNeigbors);
     foreach (var match in matches)
     {
         var neighbor = match.Pair;
         if (!Pairing.IsCandidatePaired(neighbor.Candidate) && !Pairing.IsProbePaired(neighbor.Probe))
             PairSelector.Enqueue(new EdgePair(reference, neighbor), match.Distance);
         else if (Pairing.IsProbePaired(neighbor.Probe) && Pairing.GetByProbe(neighbor.Probe).Pair.Candidate == neighbor.Candidate)
         {
             Pairing.AddSupportByProbe(reference.Probe);
             Pairing.AddSupportByProbe(neighbor.Probe);
         }
     }
 }