public KnnSearch ( Matrix |
||
queries | Matrix |
A row by row matrix of descriptors to be query for nearest neighbours |
indices | Matrix |
The result of the indices of the k-nearest neighbours |
squareDistances | Matrix |
The square of the Eculidean distance between the neighbours |
knn | int | Number of nearest neighbors to search for |
checks | int | The number of times the tree(s) in the index should be recursively traversed. A /// higher value for this parameter would give better search precision, but also take more /// time. If automatic configuration was used when the index was created, the number of /// checks required to achieve the specified precision was also computed, in which case /// this parameter is ignored |
return | void |
/// <summary> /// Find the approximate nearest position in 3D /// </summary> /// <param name="position">The position to start the search from</param> /// <param name="squareDist">The square distance of the nearest neighbour</param> /// <returns>The index with the nearest 3D position</returns> public int ApproximateNearestNeighbour(MCvPoint3D32f position, out double squareDist) { _query.Data[0, 0] = position.x; _query.Data[0, 1] = position.y; _query.Data[0, 2] = position.z; _flannIndex.KnnSearch(_query, _index, _distance, 1, 1); squareDist = _distance.Data[0, 0]; return(_index.Data[0, 0]); }
/// <summary> /// Find the approximate nearest position in 3D /// </summary> /// <param name="position">The position to start the search from</param> /// <returns>The nearest neighbor (may be an approximation, depends in the index type).</returns> public Neighbor NearestNeighbor(MCvPoint3D32f position) { _query.Data[0, 0] = position.X; _query.Data[0, 1] = position.Y; _query.Data[0, 2] = position.Z; _flannIndex.KnnSearch(_query, _index, _distance, 1, 1); Neighbor n = new Neighbor(); n.Index = _index.Data[0, 0]; n.SquareDist = _distance.Data[0, 0]; return(n); }
/* * 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); } }
public void TestFlannLinear() { float[][] features = new float[10][]; for (int i = 0; i < features.Length; i++) features[i] = new float[] { (float)i }; Flann.Index index = new Flann.Index(Util.GetMatrixFromDescriptors(features)); float[][] features2 = new float[1][]; features2[0] = new float[] { 5.0f }; Matrix<int> indices = new Matrix<int>(features2.Length, 1); Matrix<float> distances = new Matrix<float>(features2.Length, 1); index.KnnSearch(Util.GetMatrixFromDescriptors(features2), indices, distances, 1, 32); Assert.AreEqual(indices[0, 0], 5); Assert.AreEqual(distances[0, 0], 0.0); }
public void TestFlannCompositeTree() { float[][] features = new float[10][]; for (int i = 0; i < features.Length; i++) features[i] = new float[] { (float)i }; Flann.Index index = new Flann.Index(Util.GetMatrixFromDescriptors(features), 4, 32, 11, Emgu.CV.Flann.CenterInitType.RANDOM, 0.2f); float[][] features2 = new float[1][]; features2[0] = new float[] { 5.0f }; Matrix<int> indices = new Matrix<int>(features2.Length, 1); Matrix<float> distances = new Matrix<float>(features2.Length, 1); index.KnnSearch(Util.GetMatrixFromDescriptors(features2), indices, distances, 1, 32); Assert.AreEqual(indices[0, 0], 5); Assert.AreEqual(distances[0, 0], 0.0); }
public Image<Bgr, byte> DrawResult(Image<Gray, byte> modelImage, Image<Gray, byte> observedImage,out double area, int minarea, out Point center) { //double estimated_dist =99999; center = new Point(400, 224); area = 0; //modelImage.Save("D:\\temp\\modelimage.jpg"); //observedImage.Save("D:\\temp\\observedimage.jpg"); //单应矩阵 HomographyMatrix homography = null; //surf算法检测器 var surfCpu = new SURFDetector(500, false); //原图与实际图中的关键点 Matrix<byte> mask; //knn匹配的系数 var k = 2; //滤波系数 var uniquenessThreshold = 0.8; //从标记图中,提取surf特征点与描述子 var modelKeyPoints = surfCpu.DetectKeyPointsRaw(modelImage, null); var modelDescriptors = surfCpu.ComputeDescriptorsRaw(modelImage, null, modelKeyPoints); // 从实际图片提取surf特征点与描述子 var observedKeyPoints = surfCpu.DetectKeyPointsRaw(observedImage, null); var observedDescriptors = surfCpu.ComputeDescriptorsRaw(observedImage, null, observedKeyPoints); if (observedDescriptors == null) { return null; } //使用BF匹配算法,匹配特征向量 //var bfmatcher = new BruteForceMatcher<float>(DistanceType.L2); //bfmatcher.Add(modelDescriptors); var indices = new Matrix<int>(observedDescriptors.Rows, k); var flannMatcher = new Index(modelDescriptors, 4); //通过特征向量筛选匹配对 using (var dist = new Matrix<float>(observedDescriptors.Rows, k)) { //最近邻2点特征向量匹配 //bfmatcher.KnnMatch(observedDescriptors, indices, dist, k, null); flannMatcher.KnnSearch(observedDescriptors, indices, dist, k, 24); //匹配成功的,将特征点存入mask mask = new Matrix<byte>(dist.Rows, 1); mask.SetValue(255); //通过滤波系数,过滤非特征点,剩余特征点存入mask Features2DToolbox.VoteForUniqueness(dist, uniquenessThreshold, mask); } var nonZeroCount = CvInvoke.cvCountNonZero(mask); if (nonZeroCount >= 10) { //过滤旋转与变形系数异常的特征点,剩余存入mask nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20); if (nonZeroCount >= 10) //使用剩余特征点,构建单应矩阵 homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, 2); } // } //画出匹配的特征点 //Image<Bgr, Byte> result = Features2DToolbox.DrawMatches(modelImage, modelKeyPoints, observedImage, observedKeyPoints,indices, new Bgr(0, 0, 255), new Bgr(0, 255, 0), mask, Features2DToolbox.KeypointDrawType.DEFAULT); // result.Save("D:\\temp\\matchedpoints.jpg"); observedImage.ToBitmap(); var result = Features2DToolbox.DrawMatches(modelImage, modelKeyPoints, observedImage, observedKeyPoints, indices, new Bgr(0, 0, 255), new Bgr(0, 255, 0), mask, Features2DToolbox.KeypointDrawType.DEFAULT); #region draw the projected region on the Image //画出单应矩阵 if (homography != null) { var rect = modelImage.ROI; /*PointF[] pts = new PointF[] { new PointF(rect.Left, rect.Bottom), new PointF(rect.Right, rect.Bottom), new PointF(rect.Right, rect.Top), new PointF(rect.Left, rect.Top) };*/ var pts = new[] { new PointF(rect.Left + (rect.Right - rect.Left)/5, rect.Bottom - (rect.Bottom - rect.Top)/5), new PointF(rect.Right - (rect.Right - rect.Left)/5, rect.Bottom - (rect.Bottom - rect.Top)/5), new PointF(rect.Right - (rect.Right - rect.Left)/5, rect.Top + (rect.Bottom - rect.Top)/5), new PointF(rect.Left + (rect.Right - rect.Left)/5, rect.Top + (rect.Bottom - rect.Top)/5) }; //根据整个图片的旋转、变形情况,计算出原图中四个顶点转换后的坐标,并画出四边形 homography.ProjectPoints(pts); area = Getarea(pts); double xsum = 0; double ysum = 0; foreach (var point in pts) { xsum += point.X; ysum += point.Y; } center = new Point(Convert.ToInt32(xsum / 4), Convert.ToInt32(ysum / 4)); if (area > minarea) { var temp = new Image<Bgr, byte>(result.Width, result.Height); temp.DrawPolyline(Array.ConvertAll(pts, Point.Round), true, new Bgr(Color.Red), 5); //estimated_dist = GetDist(pts); var a = CountContours(temp.ToBitmap()); if (a == 2) { result.DrawPolyline(Array.ConvertAll(pts, Point.Round), true, new Bgr(Color.Red), 5); //result.Save("D:\\temp\\" + estimated_dist.ToString() + ".jpg"); } else { area = 0; //dst = estimated_dist; return result; } } } else area = 0; #endregion //dst = estimated_dist; return result; }
public void TestFlannCompositeTree() { float[][] features = new float[10][]; for (int i = 0; i < features.Length; i++) features[i] = new float[] { (float) i }; Flann.CompositeIndexParamses p = new CompositeIndexParamses(4, 32, 11, Emgu.CV.Flann.CenterInitType.Random, 0.2f); Flann.Index index = new Flann.Index(CvToolbox.GetMatrixFromArrays(features), p); float[][] features2 = new float[1][]; features2[0] = new float[] { 5.0f }; Matrix<int> indices = new Matrix<int>(features2.Length, 1); Matrix<float> distances = new Matrix<float>(features2.Length, 1); index.KnnSearch(CvToolbox.GetMatrixFromArrays(features2), indices, distances, 1, 32); EmguAssert.IsTrue(indices[0, 0] == 5); EmguAssert.IsTrue(distances[0, 0] == 0.0); }
public void TestFlannKDTree() { float[][] features = new float[10][]; for (int i = 0; i < features.Length; i++) features[i] = new float[] { (float) i }; Flann.KdTreeIndexParamses p = new KdTreeIndexParamses(4); Flann.Index index = new Flann.Index(CvToolbox.GetMatrixFromArrays(features), p); float[][] features2 = new float[1][]; features2[0] = new float[] { 5.0f }; Matrix<int> indices = new Matrix<int>(features2.Length, 1); Matrix<float> distances = new Matrix<float>(features2.Length, 1); index.KnnSearch(CvToolbox.GetMatrixFromArrays(features2), indices, distances, 1, 32); EmguAssert.IsTrue(indices[0, 0] == 5); EmguAssert.IsTrue(distances[0, 0] == 0.0); }