public double Match()
 {
     try
     {
         Transparency  = FingerprintTransparency.Current;
         ReportSupport = Transparency.AcceptsPairing();
         int totalRoots = EnumerateRoots();
         // https://sourceafis.machinezoo.com/transparency/root-pairs
         Transparency.LogRootPairs(totalRoots, Roots);
         double high = 0;
         int    best = -1;
         for (int i = 0; i < totalRoots; ++i)
         {
             double score = TryRoot(Roots[i]);
             if (best < 0 || score > high)
             {
                 high = score;
                 best = i;
             }
             ClearPairing();
         }
         // https://sourceafis.machinezoo.com/transparency/best-match
         Transparency.LogBestMatch(best);
         return(high);
     }
     catch (Exception)
     {
         CurrentInstance = new MatcherThread();
         throw;
     }
     finally
     {
         Transparency = null;
     }
 }
Esempio n. 2
0
        public void Compute(MatcherThread thread)
        {
            MinutiaCount               = thread.Count;
            MinutiaScore               = Parameters.MinutiaScore * MinutiaCount;
            MinutiaFractionInProbe     = thread.Count / (double)thread.Probe.Minutiae.Length;
            MinutiaFractionInCandidate = thread.Count / (double)thread.Candidate.Minutiae.Length;
            MinutiaFraction            = 0.5 * (MinutiaFractionInProbe + MinutiaFractionInCandidate);
            MinutiaFractionScore       = Parameters.MinutiaFractionScore * MinutiaFraction;
            SupportingEdgeSum          = 0;
            SupportedMinutiaCount      = 0;
            MinutiaTypeHits            = 0;
            for (int i = 0; i < thread.Count; ++i)
            {
                var pair = thread.Tree[i];
                SupportingEdgeSum += pair.SupportingEdges;
                if (pair.SupportingEdges >= Parameters.MinSupportingEdges)
                {
                    ++SupportedMinutiaCount;
                }
                if (thread.Probe.Minutiae[pair.Probe].Type == thread.Candidate.Minutiae[pair.Candidate].Type)
                {
                    ++MinutiaTypeHits;
                }
            }
            EdgeCount             = thread.Count + SupportingEdgeSum;
            EdgeScore             = Parameters.EdgeScore * EdgeCount;
            SupportedMinutiaScore = Parameters.SupportedMinutiaScore * SupportedMinutiaCount;
            MinutiaTypeScore      = Parameters.MinutiaTypeScore * MinutiaTypeHits;
            int    innerDistanceRadius = Doubles.RoundToInt(Parameters.DistanceErrorFlatness * Parameters.MaxDistanceError);
            double innerAngleRadius    = Parameters.AngleErrorFlatness * Parameters.MaxAngleError;

            DistanceErrorSum = 0;
            AngleErrorSum    = 0;
            for (int i = 1; i < thread.Count; ++i)
            {
                var pair          = thread.Tree[i];
                var probeEdge     = new EdgeShape(thread.Probe.Minutiae[pair.ProbeRef], thread.Probe.Minutiae[pair.Probe]);
                var candidateEdge = new EdgeShape(thread.Candidate.Minutiae[pair.CandidateRef], thread.Candidate.Minutiae[pair.Candidate]);
                DistanceErrorSum += Math.Max(innerDistanceRadius, Math.Abs(probeEdge.Length - candidateEdge.Length));
                AngleErrorSum    += Math.Max(innerAngleRadius, DoubleAngle.Distance(probeEdge.ReferenceAngle, candidateEdge.ReferenceAngle));
                AngleErrorSum    += Math.Max(innerAngleRadius, DoubleAngle.Distance(probeEdge.NeighborAngle, candidateEdge.NeighborAngle));
            }
            DistanceAccuracyScore = 0;
            AngleAccuracyScore    = 0;
            int distanceErrorPotential = Parameters.MaxDistanceError * Math.Max(0, thread.Count - 1);

            DistanceAccuracySum   = distanceErrorPotential - DistanceErrorSum;
            DistanceAccuracyScore = Parameters.DistanceAccuracyScore * (distanceErrorPotential > 0 ? DistanceAccuracySum / (double)distanceErrorPotential : 0);
            double angleErrorPotential = Parameters.MaxAngleError * Math.Max(0, thread.Count - 1) * 2;

            AngleAccuracySum   = angleErrorPotential - AngleErrorSum;
            AngleAccuracyScore = Parameters.AngleAccuracyScore * (angleErrorPotential > 0 ? AngleAccuracySum / angleErrorPotential : 0);
            TotalScore         = MinutiaScore
                                 + MinutiaFractionScore
                                 + SupportedMinutiaScore
                                 + EdgeScore
                                 + MinutiaTypeScore
                                 + DistanceAccuracyScore
                                 + AngleAccuracyScore;
            ShapedScore = Shape(TotalScore);
        }