/// <summary> /// Create k-d feature trees using the SURF feature extracted from the model image. /// </summary> /// <param name="modelFeatures">The SURF feature extracted from the model image</param> public SURFMatcher(SURFFeature[] modelFeatures) { Debug.Assert(modelFeatures.Length > 0, "Model Features should have size > 0"); _modelIndex = new Flann.Index( Util.GetMatrixFromDescriptors( Array.ConvertAll <SURFFeature, float[]>( modelFeatures, delegate(SURFFeature f) { return(f.Descriptor); })), 1); _modelFeatures = modelFeatures; }
/* * private static int CompareSimilarFeature(SimilarFeature f1, SimilarFeature f2) * { * if (f1.Distance < f2.Distance) * return -1; * if (f1.Distance == f2.Distance) * return 0; * else * return 1; * }*/ /// <summary> /// Match the SURF feature from the observed image to the features from the model image /// </summary> /// <param name="observedFeatures">The SURF feature from the observed image</param> /// <param name="k">The number of neighbors to find</param> /// <param name="emax">For k-d tree only: the maximum number of leaves to visit.</param> /// <returns>The matched features</returns> public MatchedSURFFeature[] MatchFeature(SURFFeature[] observedFeatures, int k, int emax) { if (observedFeatures.Length == 0) { return(new MatchedSURFFeature[0]); } float[][] descriptors = new float[observedFeatures.Length][]; for (int i = 0; i < observedFeatures.Length; i++) { descriptors[i] = observedFeatures[i].Descriptor; } using (Matrix <int> result1 = new Matrix <int>(descriptors.Length, k)) using (Matrix <float> dist1 = new Matrix <float>(descriptors.Length, k)) { _modelIndex.KnnSearch(Util.GetMatrixFromDescriptors(descriptors), result1, dist1, k, emax); int[,] indexes = result1.Data; float[,] distances = dist1.Data; MatchedSURFFeature[] res = new MatchedSURFFeature[observedFeatures.Length]; List <SimilarFeature> matchedFeatures = new List <SimilarFeature>(); for (int i = 0; i < res.Length; i++) { matchedFeatures.Clear(); for (int j = 0; j < k; j++) { int index = indexes[i, j]; if (index >= 0) { matchedFeatures.Add(new SimilarFeature(distances[i, j], _modelFeatures[index])); } } res[i].ObservedFeature = observedFeatures[i]; res[i].SimilarFeatures = matchedFeatures.ToArray(); } return(res); } }
/// <summary> /// Create a spill tree from the specific feature descriptors /// </summary> /// <param name="descriptors">The array of feature descriptors</param> /// <param name="naive">A good value is 50</param> /// <param name="rho">A good value is .7</param> /// <param name="tau">A good value is .1</param> public FeatureTree(float[][] descriptors, int naive, double rho, double tau) { _descriptorMatrix = Util.GetMatrixFromDescriptors(descriptors); _ptr = CvInvoke.cvCreateSpillTree(_descriptorMatrix.Ptr, naive, rho, tau); }
/// <summary> /// Create a k-d tree from the specific feature descriptors /// </summary> /// <param name="descriptors">The array of feature descriptors</param> public FeatureTree(float[][] descriptors) { _descriptorMatrix = Util.GetMatrixFromDescriptors(descriptors); _ptr = CvInvoke.cvCreateKDTree(_descriptorMatrix.Ptr); }
/// <summary> /// Finds (with high probability) the k nearest neighbors in tree for each of the given (row-)vectors in desc, using best-bin-first searching ([Beis97]). The complexity of the entire operation is at most O(m*emax*log2(n)), where n is the number of vectors in the tree /// </summary> /// <param name="descriptors">The m feature descriptors to be searched from the feature tree</param> /// <param name="results"> /// The results of the best <paramref name="k"/> matched from the feature tree. A m x <paramref name="k"/> matrix. Contains -1 in some columns if fewer than k neighbors found. /// For each row the k neareast neighbors are not sorted. To findout the closet neighbour, look at the output matrix <paramref name="dist"/>. /// </param> /// <param name="dist"> /// A m x <paramref name="k"/> matrix of the distances to k nearest neighbors /// </param> /// <param name="k">The number of neighbors to find</param> /// <param name="emax">For k-d tree only: the maximum number of leaves to visit. Use 20 if not sure</param> private void FindFeatures(float[][] descriptors, Matrix <Int32> results, Matrix <double> dist, int k, int emax) { using (Matrix <float> descriptorMatrix = Util.GetMatrixFromDescriptors(descriptors)) CvInvoke.cvFindFeatures(Ptr, descriptorMatrix.Ptr, results.Ptr, dist.Ptr, k, emax); }