OpenCvSharp特征点提取与匹配

该代码示例展示了如何利用OpenCvSharp库进行SURF特征点的检测与匹配,并通过FlannBasedMatcher筛选出高质量匹配点。在匹配过程中,还运用了RANSAC算法进行几何变换的过滤,以提高匹配的准确性。
摘要由CSDN通过智能技术生成

OpenCvSharp特征点提取与匹配

        /// <summary>
        /// 特征点Surf匹配
        /// </summary>
        /// <param name="imgSrc">输入图1</param>
        /// <param name="imgSub">输入图2</param>
        /// <param name="threshold">Surf的阈值</param>
        /// <returns></returns>
        public static Bitmap MatchPicBySurf(Bitmap imgSrc, Bitmap imgSub, double threshold = 400)
        {
            Mat matSrc = BitmapConverter.ToMat(imgSrc);
            Mat matTo = BitmapConverter.ToMat(imgSub);
            Mat matSrcRet = new Mat();
            Mat matToRet = new Mat();

            KeyPoint[] keyPointsSrc, keyPointsTo;
            var Surf = OpenCvSharp.XFeatures2D.SURF.Create(threshold, 4, 3, true, true);

            Surf.DetectAndCompute(matSrc, null, out keyPointsSrc, matSrcRet);
            Surf.DetectAndCompute(matTo, null, out keyPointsTo, matToRet);

            using (var flnMatcher = new OpenCvSharp.FlannBasedMatcher())
            {
                var matches = flnMatcher.Match(matSrcRet, matToRet);
                //求最小最大距离
                double minDistance = 1000;//反向逼近
                double maxDistance = 0;
                for (int i = 0; i < matSrcRet.Rows; i++)
                {
                    double distance = matches[i].Distance;
                    if (distance > maxDistance)
                    {
                        maxDistance = distance;
                    }
                    if (distance < minDistance)
                    {
                        minDistance = distance;
                    }
                }

                var pointsSrc = new List<Point2f>();
                var pointsDst = new List<Point2f>();
                //筛选较好的匹配点
                var goodMatches = new List<DMatch>();
                for (int i = 0; i < matSrcRet.Rows; i++)
                {
                    double distance = matches[i].Distance;
                    if (distance < Math.Max(minDistance * 2, 0.02))
                    {
                        pointsSrc.Add(keyPointsSrc[matches[i].QueryIdx].Pt);
                        pointsDst.Add(keyPointsTo[matches[i].TrainIdx].Pt);
                        //距离小于范围的压入新的DMatch
                        goodMatches.Add(matches[i]);
                    }
                }
                var outMat = new Mat();
                var pSrc = new List<Point2d>();
                var pDst = new List<Point2d>();
                //单精度点转为双精度点
                foreach (Point2f point in pointsSrc) { pSrc.Add(new Point2d(point.X, point.Y)); }
                foreach (Point2f point in pointsDst) { pDst.Add(new Point2d(point.X, point.Y)); }
                var outMask = new Mat();
                // 如果原始的匹配结果为空, 则跳过过滤步骤
                if (pSrc.Count > 0 && pDst.Count > 0)
                    // 算法RANSAC对匹配的结果做过滤
                    Cv2.FindHomography(pSrc, pDst, HomographyMethods.Ransac, mask: outMask);
                // 如果通过RANSAC处理后的匹配点大于10个,才应用过滤. 否则使用原始的匹配点结果(匹配点过少的时候通过RANSAC处理后,可能会得到0个匹配点的结果).
                if (outMask.Rows > 10)
                {
                    byte[] maskBytes = new byte[outMask.Rows * outMask.Cols];
                    outMask.GetArray(out maskBytes);
                    Cv2.DrawMatches(matSrc, keyPointsSrc, matTo, keyPointsTo, goodMatches, outMat, matchesMask: maskBytes, flags: DrawMatchesFlags.NotDrawSinglePoints);
                }
                else
                    Cv2.DrawMatches(matSrc, keyPointsSrc, matTo, keyPointsTo, goodMatches, outMat, flags: DrawMatchesFlags.NotDrawSinglePoints);
                return OpenCvSharp.Extensions.BitmapConverter.ToBitmap(outMat);
            }

        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

多巴胺耐受

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值