public override MtripletsFeature Extract(Bitmap image) { var minutiae = MinutiaeExtractor.ExtractFeatures(ImageProvider.AdaptImage(image)); var mtriplets = new List <MTriplet>(); var triplets = new Dictionary <int, int>(); foreach (var triangle in Delaunay2D.Triangulate(minutiae)) { var idxArr = new[] { (short)triangle.A, (short)triangle.B, (short)triangle.C }; var newMTriplet = new MTriplet(idxArr, minutiae); var newHash = newMTriplet.GetHashCode(); if (!triplets.ContainsKey(newHash)) { triplets.Add(newHash, 0); mtriplets.Add(newMTriplet); } } mtriplets.TrimExcess(); return(new MtripletsFeature(mtriplets, minutiae)); }
private double MatchBetaAngles(MTriplet compareTo, byte[] order) { var idxArr = new[] { 0, 1, 2, 0 }; double maxdiff = 0; for (var i = 0; i < 3; i++) { var j = idxArr[i + 1]; var qMtiai = Minutiae[MtiaIdxs[i]]; var qMtiaj = Minutiae[MtiaIdxs[j]]; var qbeta = Angle.Difference2Pi(qMtiai.Angle, qMtiaj.Angle); var tMtiai = compareTo.Minutiae[compareTo.MtiaIdxs[order[i]]]; var tMtiaj = compareTo.Minutiae[compareTo.MtiaIdxs[order[j]]]; var tbeta = Angle.Difference2Pi(tMtiai.Angle, tMtiaj.Angle); var diff = Angle.DifferencePi(qbeta, tbeta); if (diff >= AThr) { return(0); } if (diff > maxdiff) { maxdiff = diff; } } return(1 - maxdiff / AThr); }
public double Match(MTriplet target, out byte[] mtiaOrder) { byte[] matchOrder = null; double maxSimil = 0; if (Math.Abs(MaxDistance - target.MaxDistance) < DThr && Math.Abs(MidDistance - target.MidDistance) < DThr && Math.Abs(MinDistance - target.MinDistance) < DThr) { foreach (var order in Orders) { var dirSim = MatchMtiaDirections(target, order); if (dirSim == 0) { continue; } var distSim = MatchDistances(target, order); if (distSim == 0) { continue; } var betaSim = MatchBetaAngles(target, order); if (betaSim == 0) { continue; } var alphaSim = MatchAlphaAngles(target, order); if (alphaSim == 0) { continue; } var currentSimil = 1 - (1 - distSim) * (1 - alphaSim) * (1 - betaSim); if (currentSimil > maxSimil) { matchOrder = order; maxSimil = currentSimil; } } } mtiaOrder = matchOrder; return(maxSimil); }
private double MatchMtiaDirections(MTriplet compareTo, byte[] order) { double maxdiff = 0; for (var i = 0; i < 3; i++) { var qMtiai = Minutiae[MtiaIdxs[i]]; var tMtiai = compareTo.Minutiae[compareTo.MtiaIdxs[order[i]]]; var diff = Angle.DifferencePi(qMtiai.Angle, tMtiai.Angle); if (diff >= Math.PI / 4) { return(0); } if (diff > maxdiff) { maxdiff = diff; } } return(1); }
private double MatchAlphaAngles(MTriplet compareTo, byte[] order) { double maxdiff = 0; for (var i = 0; i < 3; i++) { for (var j = 0; j < 3; j++) { if (i != j) { var qMtiai = Minutiae[MtiaIdxs[i]]; var qMtiaj = Minutiae[MtiaIdxs[j]]; double x = qMtiai.X - qMtiaj.X; double y = qMtiai.Y - qMtiaj.Y; var angleij = Angle.ComputeAngle(x, y); var qAlpha = Angle.Difference2Pi(qMtiai.Angle, angleij); var tMtiai = compareTo.Minutiae[compareTo.MtiaIdxs[order[i]]]; var tMtiaj = compareTo.Minutiae[compareTo.MtiaIdxs[order[j]]]; x = tMtiai.X - tMtiaj.X; y = tMtiai.Y - tMtiaj.Y; angleij = Angle.ComputeAngle(x, y); var tAlpha = Angle.Difference2Pi(tMtiai.Angle, angleij); var diff = Angle.DifferencePi(qAlpha, tAlpha); if (diff >= AThr) { return(0); } if (diff > maxdiff) { maxdiff = diff; } } } } return(1 - maxdiff / AThr); }
private double MatchDistances(MTriplet compareTo, byte[] order) { var diff0 = Math.Abs(D[0] - compareTo.D[order[0]]); if (diff0 > DThr) { return(0); } var diff1 = Math.Abs(D[1] - compareTo.D[order[1]]); if (diff1 > DThr) { return(0); } var diff2 = Math.Abs(D[2] - compareTo.D[order[2]]); if (diff2 > DThr) { return(0); } return(1 - Math.Max(diff0, Math.Max(diff1, diff2)) / DThr); }
internal List <MtripletPair> FindSimilarMTriplets(MTriplet queryMTp) { var result = new List <MtripletPair>(); for (var j = 0; j < MTriplets.Count; j++) { var currMTp = MTriplets[j]; var currSim = queryMTp.Match(currMTp, out var currOrder); if (currSim > 0) { result.Add(new MtripletPair { QueryMTp = queryMTp, TemplateMTp = currMTp, MatchingValue = currSim, TemplateMtiaOrder = currOrder } ); } } return(result.Count > 0 ? result : null); }