public void Match() { var db = Path.Combine("FVC2000", "DB1_B"); Console.WriteLine("Matching database {0}", db); var templates = Path.Combine(TestUtils.TemplatePath, db); var personIds = (from filename in Directory.GetFiles(templates) select Path.GetFileNameWithoutExtension(filename).Split(new[] { '_' })[0]).Distinct().ToArray(); var fps = (from personId in personIds select(from filename in Directory.GetFiles(templates, personId + "_*.xml") select new FingerprintTemplate(XElement.Load(filename))).ToArray()).ToArray(); var setupTime = new TimeBenchmark(); var matchTime = new TimeBenchmark(); var nonmatchTime = new TimeBenchmark(); var matching = new List <double>(); var nonmatching = new List <double>(); foreach (var row in fps) { foreach (var probe in row) { var matcher = setupTime.Measure(() => new FingerprintMatcher(probe)); matching.AddRange(matchTime.Measure(row.Where(c => c != probe), matcher.Match)); nonmatching.AddRange(nonmatchTime.Measure(fps.Where(cr => cr != row).SelectMany(r => r), matcher.Match)); } } Console.WriteLine("{0:0} fp/s, {1:0.00}ms setup time, {2:0.00}ms final match time", nonmatchTime.Throughput, setupTime.UnitTime.TotalMilliseconds, matchTime.UnitTime.TotalMilliseconds); matching.Sort(); nonmatching.Sort(); var both = matching.Concat(nonmatching).ToList(); var thresholds = (from score in both.Concat(new[] { both.Max() + 1 }).Distinct().OrderBy(s => s) select new { Threshold = score, FMR = ApplyThreshold(nonmatching, score) / (double)nonmatching.Count, FNMR = (matching.Count - ApplyThreshold(matching, score)) / (double)matching.Count }).ToList(); var eer = thresholds.First(t => t.FNMR >= t.FMR); Console.WriteLine("EER {0:0.00%} @ threshold {1:0.0}", (eer.FMR + eer.FNMR) / 2, eer.Threshold); var fmr1k = thresholds.First(t => t.FMR <= 0.001); Console.WriteLine("FMR1000 {0:0.00%} @ threshold {1:0.0}", fmr1k.FNMR, fmr1k.Threshold); var fmr10k = thresholds.First(t => t.FMR <= 0.0001); Console.WriteLine("FMR10000 {0:0.00%} @ threshold {1:0.0}", fmr10k.FNMR, fmr10k.Threshold); }