private double MatchBetaAngles(MTriplet compareTo, byte[] order) { var idxArr = new[] { 0, 1, 2, 0 }; double maxdiff = 0; for (int i = 0; i < 3; i++) { int j = idxArr[i + 1]; Minutia qMtiai = minutiae[MtiaIdxs[i]]; Minutia qMtiaj = minutiae[MtiaIdxs[j]]; double qbeta = Angle.Difference2Pi(qMtiai.Angle, qMtiaj.Angle); Minutia tMtiai = compareTo.minutiae[compareTo.MtiaIdxs[order[i]]]; Minutia tMtiaj = compareTo.minutiae[compareTo.MtiaIdxs[order[j]]]; double tbeta = Angle.Difference2Pi(tMtiai.Angle, tMtiaj.Angle); double diff1 = Math.Abs(tbeta - qbeta); double diff = Math.Min(diff1, 2 * Math.PI - diff1); if (diff >= aThr) { return(0); } if (diff > maxdiff) { maxdiff = diff; } } return(1 - maxdiff / aThr); }
internal List <MtripletPair> FindSimilarMTriplets(MTriplet queryMTp) { var result = new List <MtripletPair>(); for (int j = 0; j < MTriplets.Count; j++) { MTriplet currMTp = MTriplets[j]; byte[] currOrder; double currSim = queryMTp.Match(currMTp, out currOrder); if (currSim > 0) { result.Add(new MtripletPair { queryMTp = queryMTp, templateMTp = currMTp, matchingValue = currSim, templateMtiaOrder = currOrder } ); } } if (result.Count > 0) { return(result); } return(null); }
internal List <MtripletPair> FindNoRotateAllSimilar(MTriplet queryMTp) { // Indexing by MaxDistance double dThr = MTriplet.DistanceThreshold; double d = queryMTp.MaxDistance - dThr; int iniIdx = BinarySearch(MTriplets, d); d = queryMTp.MaxDistance + dThr; var result = new List <MtripletPair>(); for (int j = iniIdx; j < MTriplets.Count && MTriplets[j].MaxDistance <= d; j++) { MTriplet currMTp = MTriplets[j]; byte[] currOrder; double currSim = queryMTp.NoRotateMatch(currMTp, out currOrder); if (currSim > 0) { result.Add(new MtripletPair { queryMTp = queryMTp, templateMTp = currMTp, matchingValue = currSim, templateMtiaOrder = currOrder } ); } } if (result.Count > 0) { return(result); } return(null); }
private int[] GetAlphaCodes(MTriplet mtp) { int[] alpha = new int[3]; for (int i = 0; i < 3; i++) { int j; if (i == 2) { j = 0; } else { j = i + 1; } Minutia qMtiai = mtp[i]; Minutia qMtiaj = mtp[j]; double x = qMtiai.X - qMtiaj.X; double y = qMtiai.Y - qMtiaj.Y; double angleij = Angle.ComputeAngle(x, y); double qAlpha = Angle.Difference2Pi(qMtiai.Angle, angleij); alpha[i] = DiscretizeAngle(qAlpha); } return(alpha); }
public double NoRotateMatch(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 /* && Angle.AngleDif180(maxBeta, target.maxBeta) < aThr*/) { foreach (byte[] order in Orders) { double dirSim = MatchMtiaDirections(target, order); if (dirSim == 0) { continue; } double distSim = MatchDistances(target, order); if (distSim == 0) { continue; } double betaSim = MatchBetaAngles(target, order); if (betaSim == 0) { continue; } double alphaSim = MatchAlphaAngles(target, order); if (alphaSim == 0) { continue; } double currentSimil = 1 - (1 - distSim) * (1 - alphaSim) * (1 - betaSim); if (currentSimil > maxSimil) { matchOrder = order; maxSimil = currentSimil; } } } mtiaOrder = matchOrder; return(maxSimil); }
private int[] GetAllRotationsHashes(MTriplet mtp) { // Computing hash for alpha angles int[] alphaCodes = GetAlphaCodes(mtp); // Generating all possible hashes int[] hashes = new int[3]; int i = 0; foreach (byte[] order in MTriplet.Orders) { int a0 = alphaCodes[order[0]]; int a1 = alphaCodes[order[1]]; int a2 = alphaCodes[order[2]]; hashes[i++] = MergeHashes(a0, a1, a2); } return(hashes); }
private double MatchMtiaDirections(MTriplet compareTo, byte[] order) { double maxdiff = 0; for (int i = 0; i < 3; i++) { Minutia qMtiai = minutiae[MtiaIdxs[i]]; Minutia tMtiai = compareTo.minutiae[compareTo.MtiaIdxs[order[i]]]; double 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 (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (i != j) { Minutia qMtiai = minutiae[MtiaIdxs[i]]; Minutia qMtiaj = minutiae[MtiaIdxs[j]]; double x = qMtiai.X - qMtiaj.X; double y = qMtiai.Y - qMtiaj.Y; double angleij = Angle.ComputeAngle(x, y); double qAlpha = Angle.Difference2Pi(qMtiai.Angle, angleij); Minutia tMtiai = compareTo.minutiae[compareTo.MtiaIdxs[order[i]]]; Minutia tMtiaj = compareTo.minutiae[compareTo.MtiaIdxs[order[j]]]; x = tMtiai.X - tMtiaj.X; y = tMtiai.Y - tMtiaj.Y; angleij = Angle.ComputeAngle(x, y); double tAlpha = Angle.Difference2Pi(tMtiai.Angle, angleij); double diff1 = Math.Abs(tAlpha - qAlpha); double diff = Math.Min(diff1, 2 * Math.PI - diff1); if (diff >= aThr) { return(0); } if (diff > maxdiff) { maxdiff = diff; } } } } return(1 - maxdiff / aThr); }
private double MatchDistances(MTriplet compareTo, byte[] order) { double diff0 = Math.Abs(d[0] - compareTo.d[order[0]]); if (diff0 > dThr) { return(0); } double diff1 = Math.Abs(d[1] - compareTo.d[order[1]]); if (diff1 > dThr) { return(0); } double diff2 = Math.Abs(d[2] - compareTo.d[order[2]]); if (diff2 > dThr) { return(0); } return(1 - (Math.Max(diff0, Math.Max(diff1, diff2))) / dThr); }
private double MatchMtiaDirections(MTriplet compareTo, byte[] order) { double maxdiff = 0; for (int i = 0; i < 3; i++) { Minutia qMtiai = minutiae[MtiaIdxs[i]]; Minutia tMtiai = compareTo.minutiae[compareTo.MtiaIdxs[order[i]]]; double alpha = qMtiai.Angle; double beta = tMtiai.Angle; double diff1 = Math.Abs(beta - alpha); double diff = Math.Min(diff1, 2 * Math.PI - diff1); if (diff >= Math.PI / 4) { return(0); } if (diff > maxdiff) { maxdiff = diff; } } return(1); }