/// <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; }
/// <summary> /// Create a linear flann index for 3D points /// </summary> /// <param name="points">The IPosition3D array</param> public Index3D(MCvPoint3D32f[] points) { _points = points; _dataHandle = GCHandle.Alloc(_points, GCHandleType.Pinned); _dataMatrix = new Matrix<float>(_points.Length, 3, _dataHandle.AddrOfPinnedObject()); _flannIndex = new Index(_dataMatrix); _query = new Matrix<float>(1, 3); _distance = new Matrix<float>(1, 1); _index = new Matrix<int>(1, 1); }
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; }
/// <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; }
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); }