OpenCV中文网站

 找回密码
 立即注册
搜索
热搜: 安装 配置
查看: 6897|回复: 7

emgucv中surf算法实现特征点匹配问题

[复制链接]
发表于 2016-9-29 12:52:19 | 显示全部楼层 |阅读模式
在emgucv中使用surf算法实现了特征点匹配,对于相同的特征点emgucv会进行连线,想问下有没有办法获取得连线的个数,如图

回复

使用道具 举报

发表于 2016-9-29 13:37:49 | 显示全部楼层
设置个变量,每画一条线,就让变量加1,最后不就出来了吗
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-9-29 14:09:04 | 显示全部楼层
stq002285 发表于 2016-9-29 13:37
设置个变量,每画一条线,就让变量加1,最后不就出来了吗

问题是不知道是在那里进行画线的,完整代码如下:

//点击事件
private void buttonMatch_Click(object sender, EventArgs e)
        {
            if(curBitmapDst!=null&&curBitmapSrc!=null)
            {
                long matchTime;
                //加载两张图片
                Image<Bgr, Byte> srcImg = new Image<Bgr, Byte>(curBitmapSrc);
                Image<Gray, Byte> srcImg1 = srcImg.Convert<Gray, Byte>();
                Image<Bgr, Byte> dstImg = new Image<Bgr, Byte>(curBitmapDst);
                Image<Gray, Byte> dstImg1 = dstImg.Convert<Gray, Byte>();
                Matching Match = new Matching();

                //调用Draw函数进行对比
                Image<Bgr, byte> result = Match.Draw(srcImg1,dstImg1,out matchTime);
               
                //把result图片显示出来
                Bitmap Img = result.ToBitmap();
                Form2 Form = new Form2(Img);
                Form.ShowDialog();
            }
            else
            {
                MessageBox.Show("programe error");
            }
        }

//Draw函数
public Image<Bgr, Byte> Draw(Image<Gray, Byte> modelImage, Image<Gray, byte> observedImage, out long matchTime)
        {
            HomographyMatrix homography;
            VectorOfKeyPoint modelKeyPoints;
            VectorOfKeyPoint observedKeyPoints;
            Matrix<int> indices;
            Matrix<byte> mask;

            FindMatch(modelImage, observedImage, out matchTime, out modelKeyPoints, out observedKeyPoints, out indices, out mask, out homography);

            //Draw the matched keypoints
            Image<Bgr, Byte> result = Features2DToolbox.DrawMatches(modelImage, modelKeyPoints, observedImage, observedKeyPoints,
               indices, new Bgr(255, 255, 255), new Bgr(255, 255, 255), mask, Features2DToolbox.KeypointDrawType.DEFAULT);

            #region draw the projected region on the image
            if (homography != null)
            {  //draw a rectangle along the projected model
                Rectangle 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)};
                homography.ProjectPoints(pts);

                result.DrawPolyline(Array.ConvertAll<PointF, Point>(pts, Point.Round), true, new Bgr(Color.Red), 5);
            }
            #endregion

            return result;
        }

//FindMatch函数
public static void FindMatch(Image<Gray, Byte> modelImage, Image<Gray, byte> observedImage, out long matchTime, out VectorOfKeyPoint modelKeyPoints, out VectorOfKeyPoint observedKeyPoints, out Matrix<int> indices, out Matrix<byte> mask, out HomographyMatrix homography)
      {
         int k = 2;
         double uniquenessThreshold = 0.8;
         SURFDetector surfCPU = new SURFDetector(500, false);
         Stopwatch watch;
         homography = null;
         #if !IOS
         if (GpuInvoke.HasCuda)
         {
            GpuSURFDetector surfGPU = new GpuSURFDetector(surfCPU.SURFParams, 0.01f);
            using (GpuImage<Gray, Byte> gpuModelImage = new GpuImage<Gray, byte>(modelImage))
            //extract features from the object image
            using (GpuMat<float> gpuModelKeyPoints = surfGPU.DetectKeyPointsRaw(gpuModelImage, null))
            using (GpuMat<float> gpuModelDescriptors = surfGPU.ComputeDescriptorsRaw(gpuModelImage, null, gpuModelKeyPoints))
            using (GpuBruteForceMatcher<float> matcher = new GpuBruteForceMatcher<float>(DistanceType.L2))
            {
               modelKeyPoints = new VectorOfKeyPoint();
               surfGPU.DownloadKeypoints(gpuModelKeyPoints, modelKeyPoints);
               watch = Stopwatch.StartNew();

               // extract features from the observed image
               using (GpuImage<Gray, Byte> gpuObservedImage = new GpuImage<Gray, byte>(observedImage))
               using (GpuMat<float> gpuObservedKeyPoints = surfGPU.DetectKeyPointsRaw(gpuObservedImage, null))
               using (GpuMat<float> gpuObservedDescriptors = surfGPU.ComputeDescriptorsRaw(gpuObservedImage, null, gpuObservedKeyPoints))
               using (GpuMat<int> gpuMatchIndices = new GpuMat<int>(gpuObservedDescriptors.Size.Height, k, 1, true))
               using (GpuMat<float> gpuMatchDist = new GpuMat<float>(gpuObservedDescriptors.Size.Height, k, 1, true))
               using (GpuMat<Byte> gpuMask = new GpuMat<byte>(gpuMatchIndices.Size.Height, 1, 1))
               using (Stream stream = new Stream())
               {
                  matcher.KnnMatchSingle(gpuObservedDescriptors, gpuModelDescriptors, gpuMatchIndices, gpuMatchDist, k, null, stream);
                  indices = new Matrix<int>(gpuMatchIndices.Size);
                  mask = new Matrix<byte>(gpuMask.Size);

                  //gpu implementation of voteForUniquess
                  using (GpuMat<float> col0 = gpuMatchDist.Col(0))
                  using (GpuMat<float> col1 = gpuMatchDist.Col(1))
                  {
                     GpuInvoke.Multiply(col1, new MCvScalar(uniquenessThreshold), col1, stream);
                     GpuInvoke.Compare(col0, col1, gpuMask, CMP_TYPE.CV_CMP_LE, stream);
                  }

                  observedKeyPoints = new VectorOfKeyPoint();
                  surfGPU.DownloadKeypoints(gpuObservedKeyPoints, observedKeyPoints);

                  //wait for the stream to complete its tasks
                  //We can perform some other CPU intesive stuffs here while we are waiting for the stream to complete.
                  stream.WaitForCompletion();

                  gpuMask.Download(mask);
                  gpuMatchIndices.Download(indices);

                  if (GpuInvoke.CountNonZero(gpuMask) >= 4)
                  {
                     int nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20);
                     if (nonZeroCount >= 4)
                        homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, 2);
                  }

                  watch.Stop();
               }
            }
         }
         else
         #endif
         {
            //extract features from the object image
            modelKeyPoints = new VectorOfKeyPoint();
            Matrix<float> modelDescriptors = surfCPU.DetectAndCompute(modelImage, null, modelKeyPoints);

            watch = Stopwatch.StartNew();

            // extract features from the observed image
            observedKeyPoints = new VectorOfKeyPoint();
            Matrix<float> observedDescriptors = surfCPU.DetectAndCompute(observedImage, null, observedKeyPoints);
            BruteForceMatcher<float> matcher = new BruteForceMatcher<float>(DistanceType.L2);
            matcher.Add(modelDescriptors);

            indices = new Matrix<int>(observedDescriptors.Rows, k);
            using (Matrix<float> dist = new Matrix<float>(observedDescriptors.Rows, k))
            {
               matcher.KnnMatch(observedDescriptors, indices, dist, k, null);
               mask = new Matrix<byte>(dist.Rows, 1);
               mask.SetValue(255);
               Features2DToolbox.VoteForUniqueness(dist, uniquenessThreshold, mask);
            }

            int nonZeroCount = CvInvoke.cvCountNonZero(mask);
            if (nonZeroCount >= 4)
            {
               nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20);
               if (nonZeroCount >= 4)
                  homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, 2);
            }

            watch.Stop();
         }
         matchTime = watch.ElapsedMilliseconds;
      }
回复 支持 反对

使用道具 举报

发表于 2016-12-4 14:51:10 | 显示全部楼层
话说楼主这个问题解决了吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-12-11 01:48:50 | 显示全部楼层
WGS 发表于 2016-12-4 14:51
话说楼主这个问题解决了吗?

解决了,  nonZeroCount = CvInvoke.CountNonZero(mask);

nonZeroCount 就是相似的点了
回复 支持 反对

使用道具 举报

发表于 2017-4-19 10:36:35 | 显示全部楼层
zym 发表于 2016-12-11 01:48
解决了,  nonZeroCount = CvInvoke.CountNonZero(mask);

nonZeroCount 就是相似的点了

大神   怎么比较2个特征点啊   是这样的  假如我保存了这个特征点   我在上传一张   跟这个相似的   怎么进行识别然后显示相应的信息啊
回复 支持 反对

使用道具 举报

发表于 2017-4-19 10:38:27 | 显示全部楼层
怎么判断相似度达到多少%显示相应信息呢?
回复 支持 反对

使用道具 举报

发表于 2017-4-20 17:24:39 | 显示全部楼层
大神,可以分享源代码吗
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|OpenCV中文网站

GMT+8, 2024-4-20 15:15 , Processed in 0.009603 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表