Beispiel #1
0
        private void extractFeatureButton_Click(object sender, EventArgs e)
        {
            trainingExtractSurfData = SURFMatch.CalSURFFeature(extractFeatureImage, new MCvSURFParams(500, false));
            //繪製特徵
            Image <Bgr, byte> result = Features2DToolbox.DrawKeypoints(trainingExtractSurfData.GetImg(), trainingExtractSurfData.GetKeyPoints(), new Bgr(255, 255, 255), Features2DToolbox.KeypointDrawType.DEFAULT);
            //顯示
            ImageViewer viewer = new ImageViewer(result, "Extracted Feature");

            viewer.Show();
        }
Beispiel #2
0
        //////////////////////////////////////////////////////////////////////////////////////////////

        #endregion

        #region 商家看板辨識
        //////////////////////////////////////////////////////////////////////////////////////////////
        public static SURFMatchedData MatchSURFFeature(SURFFeatureData template, Image <Bgr, Byte> observedImg, bool isShowResult)
        {
            //縮放到一樣大小 (系統修改成可讀圖片時才能加入)
            //observedImg = observedImg.Resize(3, INTER.CV_INTER_LINEAR);
            SURFFeatureData observed = SURFMatch.CalSURFFeature(observedImg);

            if (observed.GetDescriptors() != null)
            {
                SURFMatchedData matchedData = SURFMatch.MatchSURFFeatureByFLANNForObjs(template, observed);
                if (matchedData != null && isShowResult)
                {
                    SURFMatch.ShowSURFMatchForm(matchedData, observed, new ImageViewer());
                }
                return(matchedData);
            }
            else
            {
                return(null);
            }
        }
Beispiel #3
0
        private void MatchImage(object obj)
        {
            Image <Bgr, byte> senceImg      = (Image <Bgr, byte>)obj;
            SURFFeatureData   modelSurfData = ReadSURFFeature(dir.Parent.Parent.FullName + "\\SurfFeatureData\\000-0.xml");

            if (modelSurfData != null)
            {
                long              matchTime;
                int               pairCount;
                SURFFeatureData   senceSurfData = SURFMatch.CalSURFFeature(senceImage);
                Image <Bgr, byte> result        = SURFMatch.MatchSURFFeatureByBF(modelSurfData, senceSurfData, out matchTime, out pairCount);
                Console.WriteLine("match time = " + matchTime.ToString() + "ms ,PairCount = " + pairCount.ToString());
                if (result != null)
                {
                    DelegateViewer del_MatchViewer = new DelegateViewer(UpdateSURFMatchViewer);
                    this.Invoke(del_MatchViewer, result);
                    // matchViewer.Image = result;
                    //matchViewer.Show();
                    //跨執行緒UI存取,使用委派處理...
                }
            }
        }
Beispiel #4
0
 /// <summary>
 /// 計算特徵點(記得先把影像輸入到此類別中)
 /// </summary>
 /// <returns>回傳特徵資料</returns>
 public SURFFeatureData CalSURFFeature()
 {
     return(SURFMatch.CalSURFFeature(templateImg));
 }
Beispiel #5
0
        //////////////////////////////////////////////////////////////////////////////////////////////
        #endregion



        #region 匹配特徵點


        #region 物品辨識
        //////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// 比配特徵,對所有檔案匹配並找出最好的匹配檔
        /// </summary>
        /// <param name="surfFiles">載入所有可能作為匹配的特徵資料</param>
        /// <param name="observedImg">要比對觀察的影像</param>
        /// <param name="isShowResult">是否要顯示出匹配結果</param>
        /// <returns>回傳匹配到的相關資訊類別,String是檔案名稱,如果未匹配到,則Key與Values皆會回傳null,因此要先做檢查</returns>
        public static KeyValuePair <string, SURFMatchedData> MatchSURFFeatureForGoods(List <string> surfFiles, Image <Bgr, Byte> observedImg, bool isShowResult)
        {
            Dictionary <string, SURFMatchedData> matchList = new Dictionary <string, SURFMatchedData>();
            SURFFeatureData templateSURFData;
            SURFMatchedData matchedData;

            //縮放到一樣大小 (系統修改成可讀圖片時才能加入)
            //observedImg = observedImg.Resize(3, INTER.CV_INTER_LINEAR);

            //1.依序比對
            SURFFeatureData observed = SURFMatch.CalSURFFeature(observedImg);

            Console.WriteLine("### One-by-One Mathed Start.....\n============================");
            foreach (string fileName in surfFiles)
            {
                templateSURFData = MatchRecognition.ReadSURFFeature(fileName);
                Console.WriteLine("SurfData: fileName =>" + Path.GetFileName(fileName));
                matchedData = SURFMatch.MatchSURFFeatureByBruteForceForGoods(templateSURFData, observed);
                //如果Homography !=null 表示有匹配到(條件容忍與允許)
                if (matchedData.GetHomography() != null)
                {
                    matchList.Add(Path.GetFileName(fileName), matchedData);
                }
                Console.WriteLine("match num:" + matchedData.GetMatchedCount().ToString() + "\n-----------------");
            }
            //2.再找出count最大的
            int    bestMatched    = -1;
            string bestTemplateId = null; //樣板檔案名稱(Id)

            if (matchList.Count != 0)
            {
                foreach (KeyValuePair <string, SURFMatchedData> matchedSURFData in matchList)
                {
                    if (bestMatched == -1 && bestTemplateId == null)
                    {
                        bestMatched    = matchedSURFData.Value.GetMatchedCount();
                        bestTemplateId = matchedSURFData.Key;
                    }
                    else
                    {
                        //開始找出最多匹配點的檔案名稱與匹配資訊
                        if (bestMatched < matchedSURFData.Value.GetMatchedCount())
                        {
                            bestMatched    = matchedSURFData.Value.GetMatchedCount();
                            bestTemplateId = matchedSURFData.Key;
                        }
                    }
                }
                Console.WriteLine("\n**** Matched fileName=" + bestTemplateId + ", match num:" + bestMatched.ToString() + " ****");
                if (isShowResult)
                {
                    SURFMatch.ShowSURFMatchForm(matchList[bestTemplateId], observed, new ImageViewer());
                }
                Console.WriteLine("============================\n### Matched Finish.......\n");
                //回傳匹配到的類別
                return(new KeyValuePair <string, SURFMatchedData>(bestTemplateId, matchList[bestTemplateId]));
            }
            else
            {
                Console.WriteLine("\n**** No Matched fileName !");
                Console.WriteLine("============================\n### Matched Finish.......\n");
                return(new KeyValuePair <string, SURFMatchedData>(null, null));
            }
        }
Beispiel #6
0
        ////////////////////////////////////////////////////////////////////////////
        #endregion

        /// <summary>
        /// 執行辨識
        /// </summary>
        /// <param name="isDrawResultToShowOnDialog">是否要顯示出辨識的結果</param>
        /// <returns>回傳看板資訊, 格式=>"看板名稱" ;請記得做字串切割,若無比對到或有任何問題則會回傳null</returns>
        public void RunRecognition(bool isDrawResultToShowOnDialog)
        {
            SURFMatchedData   mathedObjectsData      = null;
            string            matchedFileName        = null;
            Image <Bgr, byte> observedContourRectImg = null;

            if (surfFiles.Count != 0 && histFiles.Count != 0)
            {
                Stopwatch watch = Stopwatch.StartNew();

                ////偵測物體
                foreach (string histFilePath in histFiles)
                {
                    //1.取出直方圖資料
                    DenseHistogram hist;
                    string         histFilename = System.IO.Path.GetFileName(histFilePath);
                    if (!histDatas.ContainsKey(histFilename))
                    {
                        hist = DetectObjects.ReadHistogram(histFilePath, false);
                        histDatas.Add(histFilename, hist);
                    }
                    else
                    {
                        hist = histDatas[histFilename];
                    }

                    //2.取出SURF資料
                    string templateHistFileName     = System.IO.Path.GetFileName(histFilePath); //取得路徑的檔案名稱
                    string templateSURFPathFileName = SystemToolBox.GetMappingDescriptorDataFile(templateHistFileName, dir);

                    SURFFeatureData templateSurf;
                    string          surfFilename = System.IO.Path.GetFileName(templateSURFPathFileName);
                    if (!surfDatas.ContainsKey(surfFilename))
                    {
                        templateSurf = MatchRecognition.ReadSURFFeature(templateSURFPathFileName);
                        surfDatas.Add(surfFilename, templateSurf);
                    }
                    else
                    {
                        templateSurf = surfDatas[surfFilename];
                    }

                    //3.做偵測
                    using (Image <Gray, byte> backProjectImg = DetectObjects.DoBackProject(hist, observedImg))
                        using (Image <Gray, byte> binaryImg = DetectObjects.DoBinaryThreshold(backProjectImg, 200)) {
                            Image <Gray, byte> morphologyImg = DetectObjects.DoErode(binaryImg, 2);
                            morphologyImg = DetectObjects.DoDilate(morphologyImg, 1);
                            List <Contour <System.Drawing.Point> > topContours = DetectObjects.GetOrderMaxContours(morphologyImg);

                            //new ImageViewer(DetectObjects.DrawContoursTopThreeBoundingBoxOnImg(topContours, observedImg.Copy())).Show();
                            int    i             = 0;
                            double histMatchRate = 1;
                            int    matchIndex    = -1;
                            foreach (Contour <System.Drawing.Point> c in topContours)
                            {
                                if (i == 3)
                                {
                                    break;
                                }
                                //判斷待偵測的輪廓面積是否過小,如果太小就省略
                                if (c.Area >= (templateSurf.GetImg().Width *templateSurf.GetImg().Height) * 0.4)
                                {
                                    DenseHistogram observedRectHist;
                                    observedContourRectImg = DetectObjects.GetBoundingBoxImage(c, observedImg.Copy());
                                    double compareRate = DetectObjects.CompareHistogram(hist, observedContourRectImg, out observedRectHist);
                                    if (compareRate < histMatchRate)
                                    {
                                        histMatchRate = compareRate;
                                        matchIndex    = i;
                                    }
                                    observedRectHist.Dispose();
                                }
                                i++;
                            }

                            if (histMatchRate < 0.5)
                            {
                                //影像正規化(如果觀察影像過大的話)
                                // if (observedContourRectImg != null && observedContourRectImg.Height * observedContourRectImg.Width > templateSurf.GetImg().Width * templateSurf.GetImg().Height)
                                //observedContourRectImg = observedContourRectImg.Resize(templateSurf.GetImg().Width, templateSurf.GetImg().Height, INTER.CV_INTER_LINEAR);
                                //取出特徵
                                if (obervedSurfData == null && observedContourRectImg != null)
                                {
                                    obervedSurfData = SURFMatch.CalSURFFeature(observedContourRectImg);
                                    observedContourRectImg.Dispose();
                                }
                                //匹配特徵並取回匹配到的特徵
                                SURFMatchedData mathedCandidateData = MatchRecognition.MatchSURFFeatureForVideoObjs(templateSurf, obervedSurfData, null);
                                //招出最好的特徵
                                if (mathedCandidateData != null && mathedCandidateData.GetHomography() != null)
                                {
                                    if (mathedObjectsData == null)
                                    {
                                        mathedObjectsData = mathedCandidateData;
                                        matchedFileName   = templateSURFPathFileName;
                                    }
                                    else if (mathedCandidateData.GetMatchedCount() > mathedObjectsData.GetMatchedCount() && mathedCandidateData.GetHomography() != null)
                                    {
                                        mathedObjectsData = mathedCandidateData;
                                        matchedFileName   = templateSURFPathFileName;
                                    }
                                }
                            }

                            morphologyImg.Dispose();

                            topContours.Clear();
                            if (mathedObjectsData != null && obervedSurfData != null)
                            {
                                SURFMatch.ShowSURFMatchForm(mathedObjectsData, obervedSurfData, viewer);
                            }
                        }
                }
                watch.Stop();
                Console.WriteLine("File = " + System.IO.Path.GetFileName(matchedFileName) + " Video Analytics time = " + watch.ElapsedMilliseconds);
                //if (matchedFileName != null)
                //{
                //    string[] split = System.IO.Path.GetFileName(matchedFileName).Split('b');
                //    //voice.Speak("前方有" + split[0], SpeechVoiceSpeakFlags.SVSFlagsAsync);
                //}
            }
        }