Example #1
0
 /// <summary>
 /// 建構子
 /// </summary>
 /// <param name="indices"></param>
 /// <param name="homography">用來繪製ROI的矩陣</param>
 /// <param name="mask"></param>
 /// <param name="matchedCount">匹配點</param>
 /// <param name="template">樣板特徵類別</param>
 public SURFMatchedData(Matrix <int> indices, HomographyMatrix homography, Matrix <byte> mask, int matchedCount, SURFFeatureData template)
 {
     this.indices          = indices;
     this.homography       = homography;
     this.mask             = mask;
     this.matchedCount     = matchedCount;
     this.templateSURFData = template;
 }
Example #2
0
        /// <summary>
        /// 顯示畫出匹配的視窗
        /// </summary>
        /// <param name="matchData">匹配後回傳的資料類別</param>
        /// <param name="observedScene">觀察景象特徵資料</param>
        public static void ShowSURFMatchForm(SURFMatchedData matchData, SURFFeatureData observedScene)
        {
            PointF[] matchPts = GetMatchBoundingBox(matchData.GetHomography(), matchData.GetTemplateSURFData());
            //Draw the matched keypoints
            Image <Bgr, Byte> result = Features2DToolbox.DrawMatches(matchData.GetTemplateSURFData().GetImg(), matchData.GetTemplateSURFData().GetKeyPoints(), observedScene.GetImg(), observedScene.GetKeyPoints(),
                                                                     matchData.GetIndices(), new Bgr(255, 255, 255), new Bgr(255, 255, 255), matchData.GetMask(), Features2DToolbox.KeypointDrawType.DEFAULT);

            if (matchPts != null)
            {
                result.DrawPolyline(Array.ConvertAll <PointF, Point>(matchPts, Point.Round), true, new Bgr(Color.Red), 2);
            }
            new ImageViewer(result, "顯示匹配圖像").Show();
        }
Example #3
0
        /// <summary>
        /// 匹配較快速但精確度較低
        /// </summary>
        /// <param name="template">樣板的特徵點類別</param>
        /// <param name="observedScene">被觀察的場景匹配的特徵點</param>
        /// <returns>回傳匹配的資料類別</returns>
        public static SURFMatchedData MatchSURFFeatureByFLANN(SURFFeatureData template, SURFFeatureData observedScene)
        {
            Matrix <byte>    mask;
            int              k = 2;
            double           uniquenessThreshold = 0.3;
            Matrix <int>     indices;
            HomographyMatrix homography = null;
            Stopwatch        watch;
            Matrix <float>   dists;

            try
            {
                watch = Stopwatch.StartNew();
                #region FLANN Match CPU
                //match
                Index flann = new Index(template.GetDescriptors(), 4);

                indices = new Matrix <int>(observedScene.GetDescriptors().Rows, k);
                using (dists = new Matrix <float>(observedScene.GetDescriptors().Rows, k))
                {
                    flann.KnnSearch(observedScene.GetDescriptors(), indices, dists, k, 2);
                    mask = new Matrix <byte>(dists.Rows, 1);
                    mask.SetValue(255);
                    Features2DToolbox.VoteForUniqueness(dists, uniquenessThreshold, mask);
                }
                int nonZeroCount = CvInvoke.cvCountNonZero(mask);
                Console.WriteLine("-----------------\nVoteForUniqueness pairCount => " + nonZeroCount.ToString() + "\n-----------------");
                if (nonZeroCount >= 4) //原先是4
                {
                    nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(template.GetKeyPoints(), observedScene.GetKeyPoints(), indices, mask, 1.2, 30);
                    Console.WriteLine("VoteForSizeAndOrientation pairCount => " + nonZeroCount.ToString() + "\n-----------------");
                    //filter out all unnecessary pairs based on distance between pairs

                    if (nonZeroCount >= 30)                                                                                                                             //原先是4
                    {
                        homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(template.GetKeyPoints(), observedScene.GetKeyPoints(), indices, mask, 5); //原先是5
                    }
                }
                #endregion
                watch.Stop();
                Console.WriteLine("Cal SURF Match time => " + watch.ElapsedMilliseconds.ToString() + "\n-----------------");


                return(new SURFMatchedData(indices, homography, mask, nonZeroCount, template));
            }
            catch (CvException ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.ErrorMessage);
                return(null);
            }
        }
Example #4
0
        /// <summary>
        /// 使用BruteForce匹配(較精確但較慢)
        /// </summary>
        /// <param name="template">樣板的特徵點類別</param>
        /// <param name="observedScene">被觀察的場景匹配的特徵點</param>
        /// <returns>回傳匹配的資料類別</returns>
        public static SURFMatchedData MatchSURFFeatureByBruteForce(SURFFeatureData template, SURFFeatureData observedScene)
        {
            Matrix <byte>    mask;
            int              k = 2;
            double           uniquenessThreshold = 0.5; //default:0.8
            Matrix <int>     indices;
            HomographyMatrix homography = null;
            Stopwatch        watch;

            try
            {
                watch = Stopwatch.StartNew();
                #region bruteForce match for CPU
                //match
                BruteForceMatcher <float> matcher = new BruteForceMatcher <float>(DistanceType.L2Sqr); //default:L2
                matcher.Add(template.GetDescriptors());

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

                int nonZeroCount = CvInvoke.cvCountNonZero(mask);
                Console.WriteLine("-----------------\nVoteForUniqueness pairCount => " + nonZeroCount.ToString() + "\n-----------------");
                if (nonZeroCount >= 4)
                {
                    nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(template.GetKeyPoints(), observedScene.GetKeyPoints(), indices, mask, 1.5, 30); //default:1.5 , 10, scale increment:1.5 rotatebin:50
                    Console.WriteLine("VoteForSizeAndOrientation pairCount => " + nonZeroCount.ToString() + "\n-----------------");
                    if (nonZeroCount >= 25)                                                                                                                    //defalut :4 , modify: 15
                    {
                        homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(template.GetKeyPoints(), observedScene.GetKeyPoints(), indices, mask, 5);
                    }
                }
                #endregion
                watch.Stop();
                Console.WriteLine("Cal SURF Match time => " + watch.ElapsedMilliseconds.ToString() + "\n-----------------");

                return(new SURFMatchedData(indices, homography, mask, nonZeroCount, template));
            }
            catch (CvException ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.ErrorMessage);
                return(null);
            }
        }
Example #5
0
 /// <summary>
 /// 取得對應出物體的ROI座標點
 /// </summary>
 /// <param name="homography">保存了相關匹配後的資訊(用來投影至商品上的匹配位置)</param>
 /// <param name="template">樣板特徵類別</param>
 /// <returns>回傳座標點</returns>
 public static PointF[] GetMatchBoundingBox(HomographyMatrix homography, SURFFeatureData template)
 {
     if (homography != null) //Get RoI box
     {
         //draw a rectangle along the projected model
         PointF[] pts = new PointF[] {
             new PointF(template.GetImg().ROI.Left, template.GetImg().ROI.Bottom),
             new PointF(template.GetImg().ROI.Right, template.GetImg().ROI.Bottom),
             new PointF(template.GetImg().ROI.Right, template.GetImg().ROI.Top),
             new PointF(template.GetImg().ROI.Left, template.GetImg().ROI.Top)
         };
         homography.ProjectPoints(pts); //project points
         return(pts);
     }
     else
     {
         return(null);
     }
 }