public override PointF MatchLocation(Fingerprint value, Match_Strategy strategy, double[] args) { switch(strategy) { case Match_Strategy.Single: { double min_dist = double.MaxValue; PointF best_loc = new PointF(); foreach (KeyValuePair<PointF, Fingerprint> kvp in this.loc_fingerprint_dict) { double dist = (kvp.Value as Fingerprint_S).CalcSimilarity(value as Fingerprint_S); if (dist < min_dist) { min_dist = dist; best_loc = kvp.Key; } } return best_loc; } case Match_Strategy.KNN: { if (args == null || args.Length < 1) throw new Exception("KNN匹配方法需要额外一个参数"); Dictionary<PointF, double> dists = new Dictionary<PointF, double>(); foreach (KeyValuePair<PointF, Fingerprint> kvp in this.loc_fingerprint_dict) { double dist = (kvp.Value as Fingerprint_S).CalcSimilarity(value as Fingerprint_S); dists[kvp.Key] = dist; } IOrderedEnumerable<KeyValuePair<PointF, double>> sorted = dists.OrderBy(x => x.Value); int k = (int)args[0]; int i = 0; KeyValuePair<PointF, double>[] NNs = new KeyValuePair<PointF, double>[k]; double sumr = 0; foreach(KeyValuePair<PointF, double> kvp in sorted) { if (i >= k) break; NNs[i] = kvp; sumr += 1 / kvp.Value; i++; } double mean_x = 0; double mean_y = 0; foreach(KeyValuePair<PointF, double> kvp in NNs) { mean_x += kvp.Key.X * ((1 / kvp.Value) / sumr); mean_y += kvp.Key.Y * ((1 / kvp.Value) / sumr); } return new PointF((float)mean_x, (float)mean_y); } } return new PointF(); }
/// <summary> /// 返回最匹配的位置坐标 /// </summary> /// <param name="value"></param> public PointF MatchLocation(Fingerprint value, Match_Strategy strategy, double[] args) { switch (strategy) { case Match_Strategy.Single: { double min_dist = double.PositiveInfinity; PointF best_loc = new PointF(); foreach (KeyValuePair<PointF, Dictionary<Fingerprint_Name, Fingerprint>> kvp in this.loc_fingerprint_dict) { double dist = double.PositiveInfinity; switch(value.Name) { case Fingerprint_Name.SA: dist = (kvp.Value[value.Name] as Fingerprint_SA).CalcSimilarity(value as Fingerprint_SA); break; case Fingerprint_Name.S: dist = (kvp.Value[value.Name] as Fingerprint_S).CalcSimilarity(value as Fingerprint_S); break; } if (dist < min_dist) { min_dist = dist; best_loc = kvp.Key; } } return best_loc; } case Match_Strategy.KNN: { if (args == null || args.Length < 1) throw new Exception("KNN匹配方法需要额外一个参数"); Dictionary<PointF, double> dists = new Dictionary<PointF, double>(); foreach (KeyValuePair<PointF, Dictionary<Fingerprint_Name, Fingerprint>> kvp in this.loc_fingerprint_dict) { double dist = double.PositiveInfinity; switch(value.Name) { case Fingerprint_Name.SA: dist = (kvp.Value[value.Name] as Fingerprint_SA).CalcSimilarity(value as Fingerprint_SA); break; case Fingerprint_Name.S: dist = (kvp.Value[value.Name] as Fingerprint_S).CalcSimilarity(value as Fingerprint_S); break; } dists[kvp.Key] = dist; } IOrderedEnumerable<KeyValuePair<PointF, double>> sorted = dists.OrderBy(x => x.Value); int k = (int)args[0]; int i = 0; KeyValuePair<PointF, double>[] NNs = new KeyValuePair<PointF, double>[k]; double sumr = 0; foreach (KeyValuePair<PointF, double> kvp in sorted) { if (double.IsNaN(kvp.Value)) continue; if (i >= k) break; NNs[i] = kvp; sumr += 1 / kvp.Value; i++; } double mean_x = 0; double mean_y = 0; foreach (KeyValuePair<PointF, double> kvp in NNs) { mean_x += kvp.Key.X * ((1 / kvp.Value) / sumr); mean_y += kvp.Key.Y * ((1 / kvp.Value) / sumr); } return new PointF((float)mean_x, (float)mean_y); } case Match_Strategy.KNN_HC: { if (args == null || args.Length < 1) throw new Exception("KNN匹配方法需要额外一个参数"); Dictionary<PointF, double> dists = new Dictionary<PointF, double>(); foreach (KeyValuePair<PointF, Dictionary<Fingerprint_Name, Fingerprint>> kvp in this.loc_fingerprint_dict) { double dist = double.PositiveInfinity; switch (value.Name) { case Fingerprint_Name.SA: dist = (kvp.Value[value.Name] as Fingerprint_SA).CalcSimilarity(value as Fingerprint_SA); break; case Fingerprint_Name.S: dist = (kvp.Value[value.Name] as Fingerprint_S).CalcSimilarity(value as Fingerprint_S); break; } dists[kvp.Key] = dist; } IOrderedEnumerable<KeyValuePair<PointF, double>> sorted = dists.OrderBy(x => x.Value); int k = (int)args[0]; int i = 0; List<MathUtils.MathUtility.Cluster> clusters = new List<MathUtils.MathUtility.Cluster>(); Dictionary<PointF, double> NNs = new Dictionary<PointF,double>(); foreach (KeyValuePair<PointF, double> kvp in sorted) { if (double.IsNaN(kvp.Value)) continue; if (i >= k) break; NNs.Add(kvp.Key, kvp.Value); clusters.Add(new MathUtils.MathUtility.Cluster(new List<PointF>() { kvp.Key })); i++; } new MathUtils.MathUtility().HierachicalClustering_InPlace(clusters, 2); MathUtils.MathUtility.Cluster cluster = clusters.OrderByDescending(x => x.PointNum).First(); double sum_r = 0; double wx_sum = 0; double wy_sum = 0; foreach(PointF pt in cluster.point_list) { sum_r += 1 / NNs[pt]; wx_sum += pt.X * 1 / NNs[pt]; wy_sum += pt.Y * 1 / NNs[pt]; } return new PointF((float)(wx_sum / sum_r), (float)(wy_sum / sum_r)); } } return new PointF(); }