Ejemplo n.º 1
0
        public void StateBuilder_SURFType()
        {
            // Arrange
            SURFResult result = new SURFResult()
            {
                Coordinator      = new Point(1, 1),
                Pixel            = Color.Red,
                Note             = ENote.Am,
                NumberOfElements = 12
            };

            StatesBuilder stateBuilder = new StatesBuilder(new List <IResult>()
            {
                result
            }, EModelType.SURF);

            // Act
            List <IState> states = stateBuilder.Build();

            // Arrange
            Assert.IsFalse(states.IsNullOrEmpty());
            states.ForEach(s =>
            {
                Assert.IsTrue(s.ModelType == EModelType.SURF);
                Assert.IsInstanceOfType(s, typeof(SURFState));
                Assert.IsNotNull(((SURFState)s).Element);
            });
        }
        /// <summary>
        /// SURFによる検出処理を行う
        /// </summary>
        /// <param name="dstPath"></param>
        /// <param name="srcPath"></param>
        private static SURFResult SURF(IplImage image, String srcPath, bool isDebug = false)
        {
            SURFResult result = new SURFResult();

            // cvExtractSURF
            // SURFで対応点検出

            // call cv::initModule_nonfree() before using SURF/SIFT.
            CvCpp.InitModule_NonFree();

            using (IplImage obj = Cv.LoadImage(srcPath, LoadMode.GrayScale))
            //using (IplImage image = Cv.LoadImage(dstPath, LoadMode.GrayScale))
            using (IplImage objColor = Cv.CreateImage(obj.Size, BitDepth.U8, 3))
            using (IplImage correspond = Cv.CreateImage(new CvSize(image.Width, obj.Height + image.Height), BitDepth.U8, 1))
            {
                if (isDebug)
                {
                    Cv.CvtColor(obj, objColor, ColorConversion.GrayToBgr);

                    Cv.SetImageROI(correspond, new CvRect(0, 0, obj.Width, obj.Height));
                    Cv.Copy(obj, correspond);
                    Cv.SetImageROI(correspond, new CvRect(0, obj.Height, correspond.Width, correspond.Height));
                    Cv.Copy(image, correspond);
                    Cv.ResetImageROI(correspond);
                }

                // テンプレート画像の記録
                result.templateSize = obj.GetSize();

                // SURFの処理
                CvSeq<CvSURFPoint> objectKeypoints, imageKeypoints;
                CvSeq<IntPtr> objectDescriptors, imageDescriptors;
                System.Diagnostics.Stopwatch watch = System.Diagnostics.Stopwatch.StartNew();
                {
                    using (CvMemStorage storage = Cv.CreateMemStorage(0))
                    {
                        //CvSURFParams param = new CvSURFParams(20, true);

                        Cv.ExtractSURF(obj, null, out objectKeypoints, out objectDescriptors, storage, new CvSURFParams(20, true));
                        Console.WriteLine("Object Descriptors: {0}", objectDescriptors.Total);

                        Cv.ExtractSURF(image, null, out imageKeypoints, out imageDescriptors, storage, new CvSURFParams(20000, true));
                        Console.WriteLine("Image Descriptors: {0}", imageDescriptors.Total);
                    }
                }
                watch.Stop();
                Console.WriteLine("Extraction time = {0}ms", watch.ElapsedMilliseconds);
                watch.Reset();
                watch.Start();

                // シーン画像にある局所画像の領域を線で囲む
                //CvPoint[] srcCorners = new CvPoint[4]{
                //    new CvPoint(0,0),
                //    new CvPoint(obj.Width,0),
                //    new CvPoint(obj.Width, obj.Height),
                //    new CvPoint(0, obj.Height)
                //};
                //CvPoint[] dstCorners = LocatePlanarObject(
                //    objectKeypoints, objectDescriptors,
                //    imageKeypoints, imageDescriptors,
                //    srcCorners
                //);
                //if (dstCorners != null)
                //{
                //    // 検出した領域の頂点
                //    result.dstCorners = dstCorners;

                //    for (int i = 0; i < 4; i++)
                //    {
                //        CvPoint r1 = dstCorners[i % 4];
                //        CvPoint r2 = dstCorners[(i + 1) % 4];
                //        if (isDebug)
                //        {
                //            Cv.Line(correspond, new CvPoint(r1.X, r1.Y + obj.Height), new CvPoint(r2.X, r2.Y + obj.Height), CvColor.Black);
                //        }
                //    }
                //}

                // 対応点同士を線で引く
                int[] ptPairs = FindPairs(objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors);
                for (int i = 0; i < ptPairs.Length; i += 2)
                {
                    CvSURFPoint r1 = Cv.GetSeqElem<CvSURFPoint>(objectKeypoints, ptPairs[i]).Value;
                    CvSURFPoint r2 = Cv.GetSeqElem<CvSURFPoint>(imageKeypoints, ptPairs[i + 1]).Value;

                    // 対応点を格納
                    result.findPointList.Add(r2);

                    if (isDebug)
                    {
                        Cv.Line(correspond, r1.Pt, new CvPoint(Cv.Round(r2.Pt.X), Cv.Round(r2.Pt.Y + obj.Height)), CvColor.Black);
                    }
                }

                //// 特徴点の場所に円を描く
                //for (int i = 0; i < objectKeypoints.Total; i++)
                //{
                //    CvSURFPoint r = Cv.GetSeqElem<CvSURFPoint>(objectKeypoints, i).Value;
                //    CvPoint center = new CvPoint(Cv.Round(r.Pt.X), Cv.Round(r.Pt.Y));
                //    int radius = Cv.Round(r.Size * (1.2 / 9.0) * 2);
                //    Cv.Circle(objColor, center, radius, CvColor.Red, 1, LineType.AntiAlias, 0);
                //}

                watch.Stop();
                Console.WriteLine("Drawing time = {0}ms", watch.ElapsedMilliseconds);

                // ウィンドウに表示
                if (isDebug)
                {
                    //using (CvWindow winObject = new CvWindow("Object", WindowMode.AutoSize, objColor))
                    using (CvWindow winCorrespond = new CvWindow("Object Correspond", WindowMode.AutoSize, correspond))
                    {
                        CvWindow.WaitKey(0);
                    }
                }
            }

            return result;
        }