IEnumerable<MinutiaPair> GetRoots() { const int minEdgeLength = 58; const int maxEdgeLookups = 1633; int counter = 0; var filters = new Predicate<EdgeShape>[] { shape => shape.Length >= minEdgeLength, shape => shape.Length < minEdgeLength }; foreach (var shapeFilter in filters) { for (int step = 1; step < Candidate.Minutiae.Count; ++step) for (int pass = 0; pass < step + 1; ++pass) for (int candidateReference = pass; candidateReference < Candidate.Minutiae.Count; candidateReference += step + 1) { int candidateNeighbor = (candidateReference + step) % Candidate.Minutiae.Count; var candidateEdge = new EdgeShape(Candidate, candidateReference, candidateNeighbor); if (shapeFilter(candidateEdge)) { List<IndexedEdge> matches; if (EdgeHash.TryGetValue(HashShape(candidateEdge), out matches)) { foreach (var match in matches) { if (MatchingShapes(match.Shape, candidateEdge)) { var pair = new MinutiaPair() { Probe = match.Reference, Candidate = candidateReference }; yield return pair; ++counter; if (counter >= maxEdgeLookups) yield break; } } } } } } }
double TryRoot(MinutiaPair root) { CreateRootPairing(root); BuildPairing(); return ComputeScore(); }
private static IList <MinutiaPair> GetLocalMatchingMtiae(QiFeatures query, QiFeatures template, out double[,] simArr) { var qIndex = new Dictionary <Minutia, int>(query.Minutiae.Count); var tIndex = new Dictionary <Minutia, int>(template.Minutiae.Count); var mtiaPairs = new List <MinutiaPair>(query.Minutiae.Count * template.Minutiae.Count); simArr = new double[query.Minutiae.Count, template.Minutiae.Count]; for (var i = 0; i < query.Minutiae.Count; i++) { var qMtia = query.Minutiae[i]; qIndex.Add(qMtia, i); for (var j = 0; j < template.Minutiae.Count; j++) { var tMtia = template.Minutiae[j]; var currSim = qMtia.Compare(tMtia); simArr[i, j] = currSim; if (currSim != 0) { var currMtiaPair = new MinutiaPair { QueryMtia = qMtia, TemplateMtia = tMtia, MatchingValue = currSim }; mtiaPairs.Add(currMtiaPair); } } } for (var j = 0; j < template.Minutiae.Count; j++) { tIndex.Add(template.Minutiae[j], j); } var qMatches = new Dictionary <Minutia, Minutia>(60); var tMatches = new Dictionary <Minutia, Minutia>(60); mtiaPairs.Sort(new MtiaPairComparer()); var matchingPairs = new List <MinutiaPair>(60); for (var i = 0; i < mtiaPairs.Count; i++) { var pair = mtiaPairs[i]; if (!qMatches.ContainsKey(pair.QueryMtia) || !tMatches.ContainsKey(pair.TemplateMtia)) { matchingPairs.Add(pair); if (!qMatches.ContainsKey(pair.QueryMtia)) { qMatches.Add(pair.QueryMtia, pair.TemplateMtia); } if (!tMatches.ContainsKey(pair.TemplateMtia)) { tMatches.Add(pair.TemplateMtia, pair.QueryMtia); } pair.MatchingValue = simArr[qIndex[pair.QueryMtia], tIndex[pair.TemplateMtia]]; } } return(matchingPairs); }
void CreateRootPairing(MinutiaPair root) { if (PairsByCandidate == null || PairsByCandidate.Length < Candidate.Minutiae.Count) PairsByCandidate = new PairInfo[Candidate.Minutiae.Count]; for (int i = 0; i < PairCount; ++i) { PairList[i].SupportingEdges = 0; PairsByProbe[PairList[i].Pair.Probe] = null; PairsByCandidate[PairList[i].Pair.Candidate] = null; } PairsByCandidate[root.Candidate] = PairsByProbe[root.Probe] = PairList[0]; PairList[0].Pair = root; PairCount = 1; }
private static List <MinutiaPair> GetGlobalMatchingMtiae(IList <MinutiaPair> localMatchingPairs, MinutiaPair refMtiaPair, ref int notMatchingCount) { var globalMatchingMtiae = new List <MinutiaPair>(localMatchingPairs.Count); var qMatches = new Dictionary <Minutia, Minutia>(localMatchingPairs.Count); var tMatches = new Dictionary <Minutia, Minutia>(localMatchingPairs.Count); qMatches.Add(refMtiaPair.QueryMtia, refMtiaPair.TemplateMtia); tMatches.Add(refMtiaPair.TemplateMtia, refMtiaPair.QueryMtia); var mm = new MtiaMapper(refMtiaPair.QueryMtia, refMtiaPair.TemplateMtia); var refQuery = mm.Map(refMtiaPair.QueryMtia); var refTemplate = refMtiaPair.TemplateMtia; var currNotMatchingMtiaCount = 0; int i; for (i = 0; i < localMatchingPairs.Count; i++) { var mtiaPair = localMatchingPairs[i]; if (!qMatches.ContainsKey(mtiaPair.QueryMtia) && !tMatches.ContainsKey(mtiaPair.TemplateMtia)) { var query = mm.Map(mtiaPair.QueryMtia); var template = mtiaPair.TemplateMtia; if (MatchDistance(refQuery, refTemplate, query, template) && MatchDirections(query, template) && MatchPosition(refQuery, refTemplate, query, template)) { globalMatchingMtiae.Add(mtiaPair); qMatches.Add(mtiaPair.QueryMtia, mtiaPair.TemplateMtia); tMatches.Add(mtiaPair.TemplateMtia, mtiaPair.QueryMtia); } else { currNotMatchingMtiaCount++; } } if (currNotMatchingMtiaCount >= notMatchingCount) { break; } //if (globalMatchingMtiae.Count + (localMatchingPairs.Count - i - 1) < MtiaCountThr) // break; } if (i == localMatchingPairs.Count) { notMatchingCount = currNotMatchingMtiaCount; globalMatchingMtiae.Add(refMtiaPair); return(globalMatchingMtiae); } return(null); }
private List <MinutiaPair> GetGlobalMatchingMtiae(IList <MinutiaPair> localMatchingPairs, MinutiaPair refMtiaPair) { var globalMatchingMtiae = new List <MinutiaPair>(localMatchingPairs.Count); var qMatches = new Dictionary <Minutia, Minutia>(localMatchingPairs.Count); var tMatches = new Dictionary <Minutia, Minutia>(localMatchingPairs.Count); qMatches.Add(refMtiaPair.QueryMtia, refMtiaPair.TemplateMtia); tMatches.Add(refMtiaPair.TemplateMtia, refMtiaPair.QueryMtia); MtiaMapper mm = new MtiaMapper(refMtiaPair.QueryMtia, refMtiaPair.TemplateMtia); Minutia refQuery = mm.Map(refMtiaPair.QueryMtia); Minutia refTemplate = refMtiaPair.TemplateMtia; for (int i = 1; i < localMatchingPairs.Count; i++) { MinutiaPair mtiaPair = localMatchingPairs[i]; if (!qMatches.ContainsKey(mtiaPair.QueryMtia) && !tMatches.ContainsKey(mtiaPair.TemplateMtia)) { Minutia query = mm.Map(mtiaPair.QueryMtia); Minutia template = mtiaPair.TemplateMtia; if (MatchDistance(refQuery, refTemplate, query, template) && MatchDirections(query, template) && MatchPosition(refQuery, refTemplate, query, template)) { globalMatchingMtiae.Add(mtiaPair); qMatches.Add(mtiaPair.QueryMtia, mtiaPair.TemplateMtia); tMatches.Add(mtiaPair.TemplateMtia, mtiaPair.QueryMtia); } } } globalMatchingMtiae.Add(refMtiaPair); return(globalMatchingMtiae); }
private double TryRoot(MinutiaPair root) { CreateRootPairing(root); BuildPairing(); return(ComputeScore()); }
private List <MinutiaPair> GetGlobalMatchingMtiae(List <MinutiaPair> localMatchingPairs, MinutiaPair refMtiaPair, ref int notMatchingCount) { List <MinutiaPair> globalMatchingMtiae = new List <MinutiaPair>(localMatchingPairs.Count); var qMatches = new Dictionary <Minutia, Minutia>(localMatchingPairs.Count); var tMatches = new Dictionary <Minutia, Minutia>(localMatchingPairs.Count); qMatches.Add(refMtiaPair.QueryMtia, refMtiaPair.TemplateMtia); tMatches.Add(refMtiaPair.TemplateMtia, refMtiaPair.QueryMtia); MtiaMapper mm = new MtiaMapper(refMtiaPair.QueryMtia, refMtiaPair.TemplateMtia); int currNotMatchingMtiaCount = 0; int i; for (i = 0; i < localMatchingPairs.Count; i++) { MinutiaPair mtiaPair = localMatchingPairs[i]; if (!qMatches.ContainsKey(mtiaPair.QueryMtia) && !tMatches.ContainsKey(mtiaPair.TemplateMtia)) { Minutia query = mm.Map(mtiaPair.QueryMtia); Minutia template = mtiaPair.TemplateMtia; if (dist.Compare(query, template) <= gdThr && MatchDirections(query, template) && MatchBetaAngle(refMtiaPair, mtiaPair)) { globalMatchingMtiae.Add(mtiaPair); qMatches.Add(mtiaPair.QueryMtia, mtiaPair.TemplateMtia); tMatches.Add(mtiaPair.TemplateMtia, mtiaPair.QueryMtia); } else { currNotMatchingMtiaCount++; } } if (currNotMatchingMtiaCount >= notMatchingCount) { break; } if (globalMatchingMtiae.Count + (localMatchingPairs.Count - i - 1) < MtiaCountThr) { break; } } if (i == localMatchingPairs.Count) { notMatchingCount = currNotMatchingMtiaCount; globalMatchingMtiae.Add(refMtiaPair); return(globalMatchingMtiae); } return(null); }
private IList <MinutiaPair> GetLocalMatchingMtiae(JYFeatures query, JYFeatures template) { var triplets = new List <JYTriplet>(query.Minutiae.Count * template.Minutiae.Count); for (int i = 0; i < query.Minutiae.Count; i++) { var qMtia = query.Minutiae[i]; for (int j = 0; j < template.Minutiae.Count; j++) { var tMtia = template.Minutiae[j]; double currSim = qMtia.RotationInvariantMatch(tMtia); if (currSim != 0) { JYTriplet currTriplet = new JYTriplet(); var currMtiaPair = new MinutiaPair { QueryMtia = qMtia.MainMinutia, TemplateMtia = tMtia.MainMinutia, MatchingValue = currSim }; currTriplet.MainMinutia = currMtiaPair; currMtiaPair = new MinutiaPair { QueryMtia = qMtia.NearestMtia, TemplateMtia = tMtia.NearestMtia, MatchingValue = currSim }; currTriplet.NearestMtia = currMtiaPair; currMtiaPair = new MinutiaPair { QueryMtia = qMtia.FarthestMtia, TemplateMtia = tMtia.FarthestMtia, MatchingValue = currSim }; currTriplet.FarthestMtia = currMtiaPair; currTriplet.MatchingValue = currSim; triplets.Add(currTriplet); } } } triplets.Sort(new MtiaTripletComparer()); var mtiaPairs = new List <MinutiaPair>(3 * triplets.Count); foreach (var triplet in triplets) { mtiaPairs.Add(triplet.MainMinutia); mtiaPairs.Add(triplet.NearestMtia); mtiaPairs.Add(triplet.FarthestMtia); } var qMatches = new Dictionary <Minutia, Minutia>(60); var tMatches = new Dictionary <Minutia, Minutia>(60); var matchingPairs = new List <MinutiaPair>(60); for (int i = 0; i < mtiaPairs.Count; i++) { var pair = mtiaPairs[i]; if (!qMatches.ContainsKey(pair.QueryMtia) || !tMatches.ContainsKey(pair.TemplateMtia)) { matchingPairs.Add(pair); if (!qMatches.ContainsKey(pair.QueryMtia)) { qMatches.Add(pair.QueryMtia, pair.TemplateMtia); } if (!tMatches.ContainsKey(pair.TemplateMtia)) { tMatches.Add(pair.TemplateMtia, pair.QueryMtia); } } } return(matchingPairs); }