Exhaustive template matching.

The class implements exhaustive template matching algorithm, which performs complete scan of source image, comparing each pixel with corresponding pixel of template.

The class processes only grayscale 8 bpp and color 24 bpp images.

Sample usage:

// create template matching algorithm's instance ExhaustiveTemplateMatching tm = new ExhaustiveTemplateMatching( 0.9f ); // find all matchings with specified above similarity TemplateMatch[] matchings = tm.ProcessImage( sourceImage, templateImage ); // highlight found matchings BitmapData data = sourceImage.LockBits( new Rectangle( 0, 0, sourceImage.Width, sourceImage.Height ), ImageLockMode.ReadWrite, sourceImage.PixelFormat ); foreach ( TemplateMatch m in matchings ) { Drawing.Rectangle( data, m.Rectangle, Color.White ); // do something else with matching } sourceImage.UnlockBits( data );

The class also can be used to get similarity level between two image of the same size, which can be useful to get information about how different/similar are images:

// create template matching algorithm's instance // use zero similarity to make sure algorithm will provide anything ExhaustiveTemplateMatching tm = new ExhaustiveTemplateMatching( 0 ); // compare two images TemplateMatch[] matchings = tm.ProcessImage( image1, image2 ); // check similarity level if ( matchings[0].Similarity > 0.95f ) { // do something with quite similar images }
상속: ITemplateMatching
        /// <summary>
        /// Scans rank of face cards
        /// </summary>
        /// <param name="cardImage"></param>
        /// <returns></returns>
        private Rank ScanFaceRank(Bitmap bmp)
        {
            //Initiliaze template matching class with 0.75 threshold
            ExhaustiveTemplateMatching templateMatchin = new ExhaustiveTemplateMatching(0.75f);
            Rank rank = Rank.NOT_RECOGNIZED;

            if (templateMatchin.ProcessImage(bmp, j).Length > 0) //If Jack template matches
                rank = Rank.Jack;
            if (templateMatchin.ProcessImage(bmp, k).Length > 0)//If King template matches
                rank = Rank.King;
            if (templateMatchin.ProcessImage(bmp, q).Length > 0)//If Queen template matches
                rank = Rank.Queen;

            return rank;
        }
         public TemplateMatchingResults FindTemplateInROI()
        {
            TemplateMatchingResults results = new TemplateMatchingResults();
            similarityMax = 0f;
            ExhaustiveTemplateMatching exhaustiveTemplateMatching = new ExhaustiveTemplateMatching(threshold);
            matchings = exhaustiveTemplateMatching.ProcessImage(sourceImage, templateImage, regionOfInterest);
            BitmapData data = sourceImage.LockBits(
                            new Rectangle(0, 0, sourceImage.Width, sourceImage.Height),
                            ImageLockMode.ReadWrite, sourceImage.PixelFormat);
            foreach (TemplateMatch m in matchings)
            {
                Drawing.Rectangle(data, m.Rectangle, Color.Red); // Adding rectangles in the areas of possible matches
                // do something else with matching
                if (m.Similarity > similarityMax)
                {
                    similarityMax = m.Similarity;
                }
                results.NumberOfMatches++;
            }
            sourceImage.UnlockBits(data);
            sourceImage.Save("SourceImage_Processed.bmp", ImageFormat.Bmp); //Saving the image.
         
            if (similarityMax >= threshold)
            {
                results.MatchFound = true;
            }
            else {
                results.MatchFound = false;
            }

            results.SimilarityMax = similarityMax;
            return results;
        }
예제 #3
0
        public float Match(Bitmap testBitmap)
        {
            ExhaustiveTemplateMatching tm = new ExhaustiveTemplateMatching(0);
            List<float> matches = new List<float>();
            foreach(var bmp in GetLearningSet())
                    matches.Add(tm.ProcessImage(bmp,testBitmap).First().Similarity);

            return matches.Max();
        }
예제 #4
0
        public static Point Detect(int id, Bitmap img)
        {
            ExhaustiveTemplateMatching tm = new ExhaustiveTemplateMatching(0.85f);
            TemplateMatch[] matchings = tm.ProcessImage(img, System.Drawing.Image.FromFile("images/troops/" + id + ".png") as Bitmap);

            if (matchings.Length < 1)
                return new Point(-1, -1);
            else
                return new Point(matchings[0].Rectangle.X + 37, matchings[0].Rectangle.Y + 580);
        }
예제 #5
0
 static List<Point> findPositions(Bitmap big, Bitmap small)
 {
     List<Point> result = new List<Point>();
     ExhaustiveTemplateMatching tm = new ExhaustiveTemplateMatching(0.96f);
     TemplateMatch[] matchings = tm.ProcessImage(big, small);
     foreach (TemplateMatch m in matchings)
     {
         result.Add(new Point(m.Rectangle.Location.X, m.Rectangle.Location.Y));
     }
     return result;
 }
 // 如果活动返回值,则从 CodeActivity<TResult>
 // 派生并从 Execute 方法返回该值。
 protected override void Execute(CodeActivityContext context)
 {
     var sourceimage = 原图.Get(context);
     var sim = 相似度下限.Get(context);
     var width = 查找区域宽度.Get(context);
     var height = 查找区域高度.Get(context);
     var etm = new ExhaustiveTemplateMatching(sim==null?0.9f:sim.Value);
     var match = etm.ProcessImage(sourceimage, context.GetValue(匹配图), new Rectangle(查找区域左偏移量.Get(context), 查找区域上偏移量.Get(context), width == null ? sourceimage.Width : width.Value, height == null ? sourceimage.Height : height.Value));
     context.SetValue(匹配项, match);
     if (match != null && match.Length > 0)
     {
         var bestmatch = match.OrderByDescending(q => q.Similarity).First();
         context.SetValue(最佳匹配项, bestmatch);
         var bestmatchpos = bestmatch.Rectangle.Location;
         context.SetValue(最佳匹配项坐标位置, bestmatchpos);
     }
 }
예제 #7
0
파일: Program.cs 프로젝트: ipatalas/D3Bit
		// way too slow...
		static void TestMatching()
		{
			var bitmap = (Bitmap)Bitmap.FromFile("last_screen.png");
			var template = (Bitmap)Bitmap.FromFile("pics/1920x1200/ucorner.png");

			ExhaustiveTemplateMatching tm = new ExhaustiveTemplateMatching(1f);
			// find all matchings with specified above similarity
			var sw = Stopwatch.StartNew();
			TemplateMatch[] matchings = tm.ProcessImage(bitmap, template);
			sw.Stop();
			// highlight found matchings
			BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
			foreach (TemplateMatch m in matchings)
			{
				Drawing.Rectangle(data, m.Rectangle, Color.White);
			}
			bitmap.UnlockBits(data);
		}
예제 #8
0
        //Can prob do this in parallel to speed it up
        public static string GetBestGuess(Bitmap image)
        {
            var sampleData = PreloadGuessObjects();

            var tm = new ExhaustiveTemplateMatching(0);

            foreach (var s in sampleData)
            {

                // compare two images
                TemplateMatch[] matchings = tm.ProcessImage(image.ConvertToFormat(PixelFormat.Format24bppRgb),
                    s.Bitmap.ConvertToFormat(PixelFormat.Format24bppRgb));
                // check similarity level
                s.Match = matchings[0].Similarity;
            }

            return sampleData.OrderByDescending(s => s.Match).First().Letter;
        }
예제 #9
0
 /// <summary>
 /// Determines if two images are the same
 /// </summary>
 /// <param name="expected"></param>
 /// <param name="actual"></param>
 /// <param name="differenceImage">A image showing the different is generated when not true</param>
 /// <returns></returns>
 public bool IsEqual(Stream expected, Stream actual, Action<Bitmap> differenceImage)
 {
     // convert to 24 bit
     var org = new Bitmap(expected).To24Bpp();
     var act = new Bitmap(actual).To24Bpp();
     //size check
     if (org.Size != act.Size) throw new ImagesAreNotSameSizeException(act,org);
     
     var tm = new ExhaustiveTemplateMatching(0);
     var matchings = tm.ProcessImage(org, act);
     // check similarity level; if one pixel out; fail!
     if (matchings.Length==1 && matchings[0].Similarity == 1.0f)
     {
         return true;
     }
     
     return IsDifferenceTheEscapingColor(org,act,differenceImage);
 }
예제 #10
0
        //        private const Int32 Divider = 4; // Compare to images at x4 time smaller then real resolution for speed
        public static TemplateMatch[] Contains(this Bitmap Template, Bitmap bmp, float Precision = 0.9f, Int32 Dividier = 4)
        {
            var ETM = new ExhaustiveTemplateMatching(Precision);

            try
            {
                var Matches = ETM.ProcessImage(
                    new ResizeNearestNeighbor(Template.Width / Dividier, Template.Height / Dividier).Apply(Template),
                    new ResizeNearestNeighbor(bmp.Width / Dividier, bmp.Height / Dividier).Apply(bmp)
                );

                if (Matches.Any())
                    return Matches;
                else return null;
            }
            catch (Exception Ex)
            {
                Console.WriteLine(Ex);
                return null;
            }
        }
예제 #11
0
        public static string SearchSourceInImage(string source, string tile, float similarity,string cocarea= "70|70|720|540", string cocDiamondpoints = "430,70|787,335|430,605|67,333")
        {
            try
            {
                string[] pointlist = cocDiamondpoints.Split('|');
                PointF topP = new PointF(float.Parse(pointlist[0].Split(',')[0]), float.Parse(pointlist[0].Split(',')[1]));
                PointF RightP = new PointF(float.Parse(pointlist[1].Split(',')[0]), float.Parse(pointlist[1].Split(',')[1]));
                PointF BottomP = new PointF(float.Parse(pointlist[2].Split(',')[0]), float.Parse(pointlist[2].Split(',')[1]));
                PointF LeftP = new PointF(float.Parse(pointlist[3].Split(',')[0]), float.Parse(pointlist[3].Split(',')[1]));
                List<PointF> m_Points = new List<PointF>();
                m_Points.Add(topP);
                m_Points.Add(RightP);
                m_Points.Add(BottomP);
                m_Points.Add(LeftP);
                m_Points.Add(topP);

                string[] rectarea = cocarea.Split('|');
                Rectangle r = new Rectangle(int.Parse(rectarea[0]), int.Parse(rectarea[1]), int.Parse(rectarea[2]), int.Parse(rectarea[3]));

                Bitmap bitmap1 = (Bitmap)System.Drawing.Image.FromFile(source);
                Bitmap bitmap2 = (Bitmap)System.Drawing.Image.FromFile(tile);
                Bitmap image = ImgLoc.ConvertToFormat((System.Drawing.Image)bitmap1, PixelFormat.Format24bppRgb);
                Bitmap template = ImgLoc.ConvertToFormat((System.Drawing.Image)bitmap2, PixelFormat.Format24bppRgb);
                //Rectangle r = new Rectangle(70, 70, 720, 540);
                TemplateMatch[] templateMatchArray = new ExhaustiveTemplateMatching(similarity).ProcessImage(image, template, r, m_Points);

                string str = templateMatchArray.Length.ToString();
                foreach (TemplateMatch templateMatch in templateMatchArray)
                    str = str + "|" + (templateMatch.Rectangle.X + template.Width / 2).ToString() + "|" + (templateMatch.Rectangle.Y + template.Height / 2).ToString();
                bitmap1.Dispose();
                bitmap2.Dispose();
                image.Dispose();
                template.Dispose();
                return str;
            }
            catch
            {
                return "-1";
            }
        }
 /// <summary>
 /// Scans  and returns suit of face cards.
 /// Uses template matching for recognizing suit of card
 /// </summary>
 /// <param name="bmp">Top right part of card Image</param>
 /// <param name="color">Color of card</param>
 /// <returns>Scanned Suit</returns>
 private Suit ScanFaceSuit(Bitmap bmp, char color)
 {
     //Initialize templateMatching class with 0.8 similarity threshold
     ExhaustiveTemplateMatching templateMatching = new ExhaustiveTemplateMatching(0.8f);
     Suit suit = Suit.NOT_RECOGNIZED;
 
     if (color == 'R') //If card is red then it can be hearts or diamonds
     {
         if (templateMatching.ProcessImage(bmp, hearts).Length > 0)  
             suit = Suit.Hearts; //Check If template matches for hearts
         if (templateMatching.ProcessImage(bmp, diamonds).Length > 0) 
             suit = Suit.Diamonds; //Check If template matches for diamonds
     }
     else //If its black
     {
         if (templateMatching.ProcessImage(bmp,spades).Length > 0)
             suit = Suit.Spades; //Check If template matches for spades
         if (templateMatching.ProcessImage(bmp, clubs).Length > 0)
             suit = Suit.Clubs;//Check If template matches for clubs
     }
     return suit;
 }
예제 #13
0
        public static void AutoLocate(Bot bot)
        {
            for (int x = 1; x <= 17; x++)
            {
                bot.cfgData["collectors"]["collector" + x] = "-1:-1";
            }

            Bitmap sourceImage = bot.bs.image.GetWindowImage(!Convert.ToBoolean(bot.cfgData["game"]["hidemode"]));

            ExhaustiveTemplateMatching tm = new ExhaustiveTemplateMatching(0.85f);

            int i = 1;

            TemplateMatch[] matchings = tm.ProcessImage(sourceImage, System.Drawing.Image.FromFile(AppSettings.Images.goldMine) as Bitmap);
            bot.Log(matchings.Length + " gold mine(s) found.");
            foreach (TemplateMatch m in matchings)
            {
                bot.cfgData["collectors"]["collector" + i] = (m.Rectangle.Location.X + 5) + ":" + (m.Rectangle.Location.Y + 15);
                i++;
            }

            matchings = tm.ProcessImage(sourceImage, System.Drawing.Image.FromFile(AppSettings.Images.elixirExtractor) as Bitmap);
            bot.Log(matchings.Length + " elixir extractor(s) found.");
            foreach (TemplateMatch m in matchings)
            {
                bot.cfgData["collectors"]["collector" + i] = (m.Rectangle.Location.X + 5) + ":" + (m.Rectangle.Location.Y + 15);
                i++;
            }

            matchings = tm.ProcessImage(sourceImage, System.Drawing.Image.FromFile(AppSettings.Images.darkExtractor) as Bitmap);
            bot.Log(matchings.Length + " dark elixir extractor(s) found.");
            foreach (TemplateMatch m in matchings)
            {
                bot.cfgData["collectors"]["collector" + i] = (m.Rectangle.Location.X + 5) + ":" + (m.Rectangle.Location.Y + 15);
                i++;
            }

            bot.SaveConfig();
        }
예제 #14
0
        public static bool Contains(this Bitmap template, Bitmap bmp)
        {
            const Int32 divisor = 1;
            const Int32 epsilon = 10;

            var etm = new ExhaustiveTemplateMatching(0.9f);

            var tm =
                etm.ProcessImage(
                    new ResizeNearestNeighbor(template.Width/divisor, template.Height/divisor).Apply(template),
                    new ResizeNearestNeighbor(bmp.Width/divisor, bmp.Height/divisor).Apply(bmp));

            if (tm.Length == 1)
            {
                Rectangle tempRect = tm[0].Rectangle;

                if (Math.Abs(bmp.Width / divisor - tempRect.Width) < epsilon && Math.Abs(bmp.Height / divisor - tempRect.Height) < epsilon)
                    return true;
            }

            return false;
        }
예제 #15
0
        private void AiDetection(Bitmap screenshot, Bitmap subimage, Bitmap subimage2)
        {
            try
            {
                // create template matching algorithm's instance
                // (set similarity threshold to 80%)
                AForge.Imaging.ExhaustiveTemplateMatching tm = new AForge.Imaging.ExhaustiveTemplateMatching(0.85f);
                // find all matchings with specified above similarity

                AForge.Imaging.TemplateMatch[] matchings  = tm.ProcessImage(screenshot, subimage);
                AForge.Imaging.TemplateMatch[] matchings2 = tm.ProcessImage(screenshot, subimage2);
                if (matchings.Length > 0)
                {
                    MoveCursor(matchings[0].Rectangle.Location);
                }
                else if (matchings2.Length > 0)
                {
                    MoveCursor(matchings2[0].Rectangle.Location);
                }
                else
                {
                    DialogResult result = MessageBox.Show("Auto Sub: No matchings, taking next screenshot. " +
                                                          Environment.NewLine + "If it fails three times, I would quit the program.", "No Matchings", MessageBoxButtons.RetryCancel);
                    if (result == DialogResult.Cancel)
                    {
                        Application.Exit();
                        return;
                    }
                    TakeScreenshots();
                }
            }
            catch
            {
                MessageBox.Show("Error lol");
            }
        }
예제 #16
0
 /* Assume the two images are in the correct format
  * 1 = perfectly equal
    0 = totally different */
 private double TemplateMatchingSimilarity(Bitmap image, Bitmap template)
 {
     ExhaustiveTemplateMatching tm = new ExhaustiveTemplateMatching(0);
     TemplateMatch[] matchings = tm.ProcessImage(image, template);
     return (double)matchings[0].Similarity;
 }
예제 #17
0
        public GesturePipeline(Form1 form)
            : base()
        {
            //------------------------------
            // Creates datastructures for
            // the PCSDK
            //------------------------------
            UtilMPipeline pp; //The pipeline

            PXCMGesture.Blob bdata; //The intrepred blobs
            PXCMImage bimage; //The frame from the camera
            PXCMImage.ImageData data; //The data contained in the frame.
            PXCMImage.ImageInfo info; //Metadata about the frame.
            int color; //The "color" for the hand in question.
            //------------------------------

            //------------------------------
            // Initilize the datastructures
            // defined above.
            //------------------------------
            Coord[] locations;
            pp = new UtilMPipeline();
            pp.EnableGesture();
            pp.EnableImage(PXCMImage.ColorFormat.COLOR_FORMAT_DEPTH);
            //-----------------------------

            //initilize the pointer for the WMC window.
            IntPtr handle = GetDesktopWindow();

            //----------------------------------
            // Create and initilize the bitmaps
            // that the frames will be comapred
            // against.
            //---------------------------------
            Bitmap pause = convertBitmap(KwisStandalone.Properties.Resources.STOP);
            Bitmap fastForward = convertBitmap(KwisStandalone.Properties.Resources.FAST_FORWARD);
            Bitmap rewind = convertBitmap(KwisStandalone.Properties.Resources.REWIND);
            Bitmap play = convertBitmap(KwisStandalone.Properties.Resources.PLAY);
            Bitmap menu = convertBitmap(KwisStandalone.Properties.Resources.MENU);
            Bitmap volUp = convertBitmap(KwisStandalone.Properties.Resources.VOL_UP);
            Bitmap volDown = convertBitmap(KwisStandalone.Properties.Resources.VOL_DOWN);
            //--------------------------------

            // initial the template matching algorithm.
            templateMatching = new ExhaustiveTemplateMatching(0.75f);

            /* If we were able to aquire a frame from the camera,
             * start the main application logic.
             * */
            if (pp.Init())
            {

                //Loop forever as long as the form is still open.
                while (!form.closing)
                {
                    if (!pp.AcquireFrame(true))
                    {
                        MessageBox.Show("Failed to aquire a frame.", "Kwi-S", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk);
                        break;
                    }

                    //Aquire the gesture data for the frame.
                    using (PXCMGesture gesture = pp.QueryGesture())
                    {

                        //Load gesture data into respective data structures.
                        gesture.QueryBlobData(PXCMGesture.Blob.Label.LABEL_SCENE, 0, out bdata);
                        gesture.QueryBlobImage(PXCMGesture.Blob.Label.LABEL_SCENE, 0, out bimage);
                        bimage.AcquireAccess(PXCMImage.Access.ACCESS_READ, out  data);
                        info = bimage.imageInfo;

                        /* Although this says left hand,
                         * this actually aquires the right hand.
                         * This is from trial and error and contradicts
                         * both the documentation and common sense.  A bug
                         * in the SDK?
                         * */
                        color = (int)bdata.labelLeftHand;

                        //Store the pixels that include the hand specified above.
                        locations = new Coord[info.width * info.height];
                        handLocation(ref locations, data, (int)info.width);

                        //create a new bitmap from this data.
                        Bitmap bitmap = createBitmap(ref locations, (int)info.width, (int)info.height);

                        /* Zero is the left hand (actuall right).  So, if we detected this,
                         * then lets see if it matches any of the stored reference images.
                         * */
                        if (color == 0)
                        {

                            try
                            {
                                if (compare(ref bitmap, ref  pause))
                                {
                                    clickAndSendKey(RemoteKey.PLAY_PAUSE);

                                }
                                else if (compare(ref bitmap, ref play))
                                {

                                    clickAndSendKey(RemoteKey.PLAY);
                                }
                                else if (compare(ref bitmap, ref fastForward))
                                {

                                    clickAndSendKey(RemoteKey.FAST_FORWARD);
                                }

                                else if (compare(ref bitmap, ref rewind))
                                {
                                    clickAndSendKey(APPCOMMAND_MEDIA_REWIND, handle);
                                }
                                else if (compare(ref bitmap, ref menu))
                                {

                                    clickAndSendKey(RemoteKey.STOP);
                                }
                                else if (compare(ref bitmap, ref volUp))
                                {
                                   clickAndSendKey(RemoteKey.VOL_UP);
                                }
                                else if (compare(ref bitmap, ref volDown))
                                {

                                    clickAndSendKey(RemoteKey.VOL_DOWN);
                                }

                            }
                            catch (InvalidImagePropertiesException iipe)
                            {

                            }

                        }

                        //Clean up the datastructures in prep for a new frame.
                        bitmap.Dispose();
                        bimage.ReleaseAccess(ref data);
                        bimage.Dispose();
                        gesture.Dispose();
                    }

                    pp.ReleaseFrame();
                }
            }
        }
예제 #18
0
        private void Detect(object sender, DoWorkEventArgs e)
        {
            while (true)
            {
                bool forced = capture.WaitOne(TimeSpan.FromSeconds(3));
                using (Graphics g = Graphics.FromImage(current))
                {
                    //WriteLog(String.Format("Detect, forced={0}", forced));
                    Mouse.Click(new Point(bounds.Location.X, bounds.Location.Y + 120), new[] { Mouse.MouseEvent.LeftDown, Mouse.MouseEvent.LeftUp });
                    g.CopyFromScreen(bounds.Location, Point.Empty, bounds.Size);

                    lock (locker)
                    {
                        tasks.Clear();
                    }

                    ExhaustiveTemplateMatching actionMatching = new ExhaustiveTemplateMatching { SimilarityThreshold = 0.88f };
                    ExhaustiveTemplateMatching buttonMatching = new ExhaustiveTemplateMatching { SimilarityThreshold = 0.90f };
                    BlobCounter actions = new BlobCounter { FilterBlobs = true, MinWidth = 25, MinHeight = 25, MaxWidth =  42, MaxHeight = 42 };
                    BlobCounter buttons = new BlobCounter { FilterBlobs = true, MinWidth = 60, MinHeight = 25, MaxWidth = 175, MaxHeight = 50 };
                    Bitmap yellowOnly = keepYellowOnly.Apply(current);
                    //keepYellowOnly.ApplyInPlace(current); Bitmap yellowOnly = current;
                    actions.ProcessImage(yellowOnly);
                    buttons.ProcessImage(yellowOnly);

                    //int n = 0;
                    ////keepYellowOnly.ApplyInPlace(current);   // output image with color filter applied
                    ////foreach (Blob blob in buttons.GetObjectsInformation().Concat(actions.GetObjectsInformation()))
                    ////    if (!templates.Where(t => t.Icon.Height <= blob.Rectangle.Height && t.Icon.Width <= blob.Rectangle.Width)
                    ////                    .Any(t => exhaustive.ProcessImage(current, t.Icon, blob.Rectangle).Length == 0))
                    //foreach (Blob blob in buttons.GetObjectsInformation().Concat(actions.GetObjectsInformation()))
                    //{
                    //    //if (blob.Rectangle.ToString().StartsWith("{X=1291,Y=406"))
                    //    //{
                    //    //    i += 0;
                    //    //    var x = actionMatching.ProcessImage(current, templates[11].Icon, blob.Rectangle);
                    //    //}
                    //    using (Bitmap icon = new Bitmap(blob.Rectangle.Width, blob.Rectangle.Height))
                    //    using (Graphics g1 = Graphics.FromImage(icon))
                    //    {
                    //        icon.SetResolution(current.HorizontalResolution, current.VerticalResolution);
                    //        g1.DrawImage(current, 0, 0, blob.Rectangle, GraphicsUnit.Pixel);
                    //        //g.DrawString(String.Format("{0}", blob.Rectangle),
                    //        //    new Font("Arial", 10, FontStyle.Bold), Brushes.Black, blob.Rectangle.Location);
                    //        icon.Save(String.Format(@"C:\Users\Rubens\Desktop\simcity\{0}.jpg", ++n), ImageFormat.Jpeg);
                    //    }
                    //    g.FillRectangle(new SolidBrush(Color.FromArgb(128, Color.Yellow)), blob.Rectangle);
                    //}
                    ////current.Save(@"C:\Users\Rubens\Desktop\newIconXXX.png");

                    #region Identify actions and buttons

                    var items =
                            actions.GetObjectsInformation()
                                   .SelectMany(a => templates.Where (t => t.Icon.Height <= a.Rectangle.Height &&
                                                                          t.Icon.Width  <= a.Rectangle.Width)
                                                             .Select(t => new
                                                             {
                                                                 Template = t,
                                                                 Blob = a,
                                                                 Match = actionMatching.ProcessImage(current, t.Icon, a.Rectangle)
                                                                                       .OrderBy(i => i.Similarity).FirstOrDefault()
                                                             })).Concat(
                            buttons.GetObjectsInformation()
                                   .SelectMany(a => templates.Where (t => t.Icon.Height <= a.Rectangle.Height &&
                                                                          t.Icon.Width  <= a.Rectangle.Width)
                                                             .Select(t => new
                                                             {
                                                                 Template = t,
                                                                 Blob = a,
                                                                 Match = buttonMatching.ProcessImage(current, t.Icon, a.Rectangle)
                                                                                       .OrderBy(i => i.Similarity).FirstOrDefault()
                                                             })))
                            .Where(i => i       != null)
                            .Where(i => i.Match != null)
                            .OrderByDescending(i => i.Match.Similarity);

                    foreach (var item in items)
                    {
                        Rectangle target = CalculateOffset(item.Match.Rectangle, item.Template.Offset);
                        g.FillRectangle(new SolidBrush(Color.FromArgb(128, item.Template.Color)), item.Match.Rectangle);
                        g.FillRectangle(Brushes.HotPink, target);   // click point
                        //g.DrawString(String.Format("{0},{1},{2} ({3:0.00})", target.Location, template.Priority, template.Name, match.Similarity),
                        //    new Font("Arial", 10, FontStyle.Bold), Brushes.Black, target.Location);

                        if (!item.Template.AutoClick)
                            continue;   // Auto level up?

                        Point location = TranslateScreenCoordinates(target);
                        Task task = new Task
                        {
                            Priority    = item.Template.Priority,
                            Location    = location,
                            MouseEvents = new[] { Mouse.MouseEvent.LeftDown, Mouse.MouseEvent.LeftUp },
                            Type        = item.Template.Name,
                            LastClick   = tracker.ContainsKey(location) ? tracker[location]: DateTime.MinValue,
                            Cost        = item.Template.Cost,
                            Delay       = item.Template.Delay,
                            Refresh     = item.Template.Refresh,
                            Similarity  = item.Match.Similarity
                        };

                        lock (locker)
                        {
                            // no existing task on same location
                            if (tasks.All(t => t.Location != task.Location))
                            {
                                tasks.Add(task);
                            }
                        }
                    }

                    lock (locker)
                    {   // Acumular as tarefas antes de executar
                        System.Threading.Monitor.Pulse(locker);
                    }

                    #endregion

                    Refresh();
                }
            }
        }
예제 #19
0
 public float IsMatch(Bitmap source, Bitmap template, float threshold = 0.80f)
 {
     var tm = new ExhaustiveTemplateMatching(threshold);
     var matchings = tm.ProcessImage(source, template);
     return matchings.Length > 0 ? matchings[0].Similarity : -1;
 }
예제 #20
0
        public bool IsButton(Bitmap source, Bitmap template)
        {
            template = Resources.dealer;
            var temp = source.Clone() as Bitmap; //Clone image to keep original image

            //var seq = new FiltersSequence();
            //seq.Add(Grayscale.CommonAlgorithms.BT709);
            ////seq.Add(new OtsuThreshold()); //Then add binarization(thresholding) filter
            //temp = seq.Apply(source); // Apply filters on source image
            //var templ = seq.Apply(template);

            var templ = template;

            //var extractor = new BlobCounter();
            //extractor.ProcessImage(temp);

            ////Will be used transform(extract) cards on source image
            ////QuadrilateralTransformation quadTransformer = new QuadrilateralTransformation();

            //foreach (Blob blob in extractor.GetObjectsInformation())
            //{

            //    var cardImg = source.Clone(blob.Rectangle, PixelFormat.DontCare);
            //}

            //return false;
            var templateMatchin = new ExhaustiveTemplateMatching(0.8f);
            TemplateMatch[] templates;
            if (
                temp.Width < template.Width
                ||
                temp.Height < template.Height
                )
                templates = templateMatchin.ProcessImage(templ, temp);
            else
                templates = templateMatchin.ProcessImage(temp, templ);

            return templates.Length > 0;
        }
예제 #21
0
        private bool IsNotNumber(Bitmap source)
        {
            var template = Resources.PlayerEmpty;
            var temp = source.Clone() as Bitmap; //Clone image to keep original image

            var seq = new FiltersSequence();
            seq.Add(Grayscale.CommonAlgorithms.BT709);
            temp = seq.Apply(source); // Apply filters on source image

            var templ = seq.Apply(template);

            var templateMatchin = new ExhaustiveTemplateMatching(0.9f);
            TemplateMatch[] templates;
            if (
                temp.Width < template.Width
                ||
                temp.Height < template.Height
                )
                templates = templateMatchin.ProcessImage(templ, temp);
            else
                templates = templateMatchin.ProcessImage(temp, templ);

            var res = templates.Length > 0;

            template = Resources.PlayerMissing;
            templ = seq.Apply(template);

            templateMatchin = new ExhaustiveTemplateMatching(0.9f);
            TemplateMatch[] templates2;
            if (
                temp.Width < template.Width
                ||
                temp.Height < template.Height
                )
                templates2 = templateMatchin.ProcessImage(templ, temp);
            else
                templates2 = templateMatchin.ProcessImage(temp, templ);

            res |= templates2.Length > 0;
            return res;
        }
예제 #22
0
        public bool ScanByTemplate(Bitmap source, Bitmap template)
        {
            var temp = source.Clone() as Bitmap; //Clone image to keep original image
            var tempTempl = template;

            var seq = new FiltersSequence();
            seq.Add(Grayscale.CommonAlgorithms.BT709);  //First add  grayScaling filter
            //seq.Add(new Threshold(200));
            seq.Add(new OtsuThreshold()); //Then add binarization(thresholding) filter
            temp = seq.Apply(source); // Apply filters on source image

            //tempTempl = seq.Apply(template); // Apply filters on source image

            var templateMatchin = new ExhaustiveTemplateMatching(0.9f);
            TemplateMatch[] templates;
            templates = templateMatchin.ProcessImage(temp, tempTempl);

            return templates.Length > 0;
        }
예제 #23
0
 /// <summary>
 ///   Constructs a new <see cref="MatchingTracker"/> object tracker.
 /// </summary>
 /// 
 public MatchingTracker()
 {
     matcher = new ExhaustiveTemplateMatching(0);
     crop = new Crop(Rectangle.Empty);
     trackingObject = new TrackingObject();
 }
예제 #24
0
        private void btnStart_Click(object sender, EventArgs e)
        {
            if (_NeedHelp && _EmptySlotNumber == -1)
            {
                MessageBox.Show("ก็บอกว่าขอตัวช่วยไง !! -->  ช่วยกำหนดตำแหน่งช่องว่างให้จอมยุทธน้อยหน่อยซิ !!!");
                return;
            }

            this.Cursor = Cursors.WaitCursor;

            flowLayoutPanel1.Controls.Clear();
            flowLayoutPanel2.Controls.Clear();

            ExhaustiveTemplateMatching tm = new ExhaustiveTemplateMatching(0);

            frPerfectImage.Hide();
            frPuzzleImage.Hide();

            screenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format24bppRgb);
            Graphics gfxScreenshot = Graphics.FromImage(screenshot);
            gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);


            Bitmap[] PiecesPerfectImage = this.getPerfectImagePieces();
            Bitmap[] PiecesPuzzleImage = this.getPuzzleImagePieces();
            ClickPosition = this.getClickArea(PiecesPuzzleImage.Length);

            int width = PiecesPerfectImage[0].Width;
            int Height = PiecesPerfectImage[0].Height;

            for (int i = 0; i < PiecesPuzzleImage.Length; i++)
            {
                PiecesPuzzleImage[i] = new Bitmap(PiecesPuzzleImage[i], PiecesPerfectImage[0].Width, PiecesPerfectImage[0].Height);
                PiecesPuzzleImage[i] = PiecesPuzzleImage[i].Clone(new Rectangle(0, 0, PiecesPerfectImage[i].Width, PiecesPerfectImage[i].Height), PixelFormat.Format24bppRgb);
            }

            string Output = string.Empty;
            string ss = string.Empty;

            int[] PiecesNumber = new int[PiecesPuzzleImage.Length];
            float[] scoreMax = new float[PiecesPuzzleImage.Length];

            //Init All Pieces number = -1 ไว้เช็คภาพที่โดนเลือกไปแล้ว
            for (int i = 0; i < PiecesNumber.Length; i++)
            {
                PiecesNumber[i] = -1;
            }

            //วิธีใหม่
            float[,] scoreAll = new float[PiecesPuzzleImage.Length, PiecesPuzzleImage.Length];
            int[] PiecesNumberNew = new int[PiecesPuzzleImage.Length];

            for (int i = 0; i < PiecesPuzzleImage.Length; i++)
            {
                if (i == _EmptySlotNumber)
                {
                    scoreMax[i] = 0;
                    PiecesNumber[i] = 8;

                    //New
                    for (int k = 0; k < PiecesPuzzleImage.Length; k++)
                    {
                        scoreAll[i, k] = 0;
                    }
                    PiecesNumberNew[i] = 8;

                    continue;
                }

                //float[] score = new float[PiecesPuzzleImage.Length];

                //ภาพสุดท้ายไม่ต้อง compare เพราะมันเป็นช่องว่าง
                for (int j = 0; j < PiecesPerfectImage.Length - 1; j++)
                {
                    //if (PiecesNumber[j] != j
                    //    || i == PiecesPuzzleImage.Length - 1)//รูปสุดท้าย compare หมด แต่รูป 1 ถึงรูปก่อนสุดท้าย compare เฉพาะรูปที่ยังไม่ถูกเลือก
                    //{//ยังไม่โดนเลือก
                    TemplateMatch[] matchings = tm.ProcessImage(PiecesPuzzleImage[i], PiecesPerfectImage[j]);
                    //score[j] = matchings[0].Similarity;//Max Similarity

                    scoreAll[i, j] = matchings[0].Similarity;
                    //}
                    //else
                    //{
                    //    score[j] = 0; //score ต่ำ --> จะไม่ถูกเลือกซ้ำอีก
                    //}

                    //ss += score[j].ToString() + " - ";
                }//end for (int j = 0; j < PiecesPerfectImage.Length; j++)

                //int PieceNumber = -1;
                //float maxScore = score.Max();

                //scoreMax[i] = maxScore;
                //PiecesNumber[i] = Array.IndexOf(score, maxScore);

                //if (maxScore <= float.Parse(tbScore.Text))
                //{//เป็นช่องว่าง
                //    PieceNumber = PiecesPerfectImage.Length - 1;
                //}
                //else
                //{
                //    PieceNumber = Array.IndexOf(score, maxScore);
                //}

                //PiecesNumber[i] = PieceNumber;



                //Output += Environment.NewLine;

                //if (checkBox1.Checked)
                //{
                //    //show Image for testing
                //    PictureBox tmp = new PictureBox();
                //    tmp.Image = PiecesPerfectImage[i];
                //    tmp.Size = new Size(100, 100);
                //    flowLayoutPanel1.Controls.Add(tmp);

                //    PictureBox tmp2 = new PictureBox();
                //    tmp2.Image = PiecesPuzzleImage[i];
                //    tmp2.Size = new Size(100, 100);
                //    flowLayoutPanel2.Controls.Add(tmp2);
                //}

                ss += Environment.NewLine;
            }//end for (int i = 0; i < PiecesPuzzleImage.Length; i++)



            //set ตำแหน่งช่องว่าง โดยการใช้ score.Min 
            //PiecesNumber[Array.IndexOf(scoreMax, scoreMax.Min())] = PiecesNumber.Length - 1;

            //int EmptyIndex = Array.IndexOf(PiecesNumber, PiecesPerfectImage.Length - 1);
            //if (EmptyIndex == -1)
            //{// แปลว่าหา EmptySlot ไม่เจอ
            //    PiecesNumber[Array.IndexOf(scoreMax, scoreMax.Min())] = PiecesPerfectImage.Length - 1;
            //}


            //foreach (int a in PiecesNumber)
            //{
            //    Output += a.ToString() + ",";
            //}

            //MessageBox.Show(Output + Environment.NewLine + ss);


            //New
            int[] AssignedPieces = new int[PiecesPuzzleImage.Length];

            for (int i = 0; i < AssignedPieces.Length; i++)
            {
                AssignedPieces[i] = -1;
            }

            for (int i = 0; i < AssignedPieces.Length; i++)
            {
                //Set EmptySlot
                if (i == _EmptySlotNumber)
                {
                    AssignedPieces[i] = AssignedPieces.Length - 1;
                    continue;
                }

                float maxScore = 0f;
                int maxScoreIndex = -1;



                for (int j = 0; j < PiecesPuzzleImage.Length; j++)
                {
                    if (Array.IndexOf(AssignedPieces, j) == -1)
                    {
                        if (scoreAll[i, j] > maxScore)
                        {
                            maxScore = scoreAll[i, j];
                            maxScoreIndex = j;
                        }
                    }
                    else
                    {

                    }
                }
                AssignedPieces[i] = maxScoreIndex;
            }

            long time = DateTime.Now.Ticks;


            try
            {

                int countStep = 0;
                steps = AutoSlidingTile.JigsawSolver.Process((int)System.Math.Sqrt(AssignedPieces.Length), AssignedPieces, ref countStep);

                //steps = AutoSlidingTile.Solver.Process((int)System.Math.Sqrt(PiecesNumber.Length), PiecesNumber);
            }
            catch (Exception ex)
            {//
                //this.Size = new Size(207, 391);

                string tmp = string.Empty;

                foreach (int a in AssignedPieces)
                {
                    tmp += a.ToString() + ", ";
                }

                if (_NeedHelp)
                {
                    MessageBox.Show("ข้าน้อยไร้ความสามารถ พวกท่านแก้กันเองแล้วกัน !!!!!" + Environment.NewLine + tmp.ToString());
                }
                else
                {
                    _NeedHelp = true;

                    MessageBox.Show("ขอตัวช่วย --> เลือกช่องว่างให้จอมยุทธน้อยทีเถ๊อะ !!!!" + Environment.NewLine + tmp.ToString());
                }
                this.Cursor = Cursors.Default;
                frPerfectImage.Show();
                frPuzzleImage.Show();
                return;
            }

            this.Cursor = Cursors.Default;

            duration = (int)(tbDuration.Value * 1000);
            if (steps != null)
            {
                //    for (int i = 0; i < steps.Length; i++)
                //    {
                //        this.sendMouseClick(ClickPosition[steps[i]].X, ClickPosition[steps[i]].Y, duration);
                //    }

                //    //แก้ปัญหาที่มันค้างในการกดครั้งสุดท้าย
                //    this.sendMouseClick(ClickPosition[steps[steps.Length - 1]].X, ClickPosition[steps[steps.Length - 1]].Y, duration);
                frPerfectImage.Hide();
                frPuzzleImage.Hide();

                isClicking = true;
                Worker = new Thread(this.EndPuzzle);
                Worker.Start();
            }
            else
            {
                string tmp = string.Empty;

                foreach (int a in AssignedPieces)
                {
                    tmp += a.ToString() + ", ";
                }
                this.Cursor = Cursors.Default;
                frPerfectImage.Show();
                frPuzzleImage.Show();
                MessageBox.Show("เจอปัญหาแล้วจ้า !!  steps = null" + Environment.NewLine + tmp.Substring(0, tmp.Length - 2));
            }

            this.ClearForm();
        }
        public TemplateMatchingResults FindTemplateInImageExhaustively()
        {
            TemplateMatchingResults results = new TemplateMatchingResults();
            int i = 0;
            int divisor;
            similarityMax = 0f;
            ExhaustiveTemplateMatching exhaustiveTemplateMatching = new ExhaustiveTemplateMatching(threshold);
            results.MatchFound = false;
            while ((results.MatchFound == false) && (i < pyramidLevels))
            {
                divisor = pyramidLevels - i;
                if (divisor != 0){
                    Rectangle sourceImageRegion = new Rectangle(0, 0, sourceImage.Width / divisor, sourceImage.Height / divisor);
                    matchings = exhaustiveTemplateMatching.ProcessImage(sourceImage, templateImage, sourceImageRegion);

                    foreach (TemplateMatch m in matchings){
                        if (m.Similarity > threshold){
                            results.MatchFound = true;
                            results.NumberOfMatches++;
                            if (m.Similarity > similarityMax){
                                similarityMax = m.Similarity;
                            }
                        }
                        else {
                            results.MatchFound = false;
                        }
                    }
                }
                i++;
            }
            results.SimilarityMax = similarityMax;
            return results;

        }
예제 #26
0
파일: RecogNums.cs 프로젝트: bdus/AForge
        private void dealpb_1(Bitmap machImg)
        {
            Bitmap[] files = {
               global::AForgeImaging.Properties.Resources._0,
               global::AForgeImaging.Properties.Resources._1,
               global::AForgeImaging.Properties.Resources._2,
               global::AForgeImaging.Properties.Resources._3,
               global::AForgeImaging.Properties.Resources._4,
               global::AForgeImaging.Properties.Resources._5,
               global::AForgeImaging.Properties.Resources._6,
               global::AForgeImaging.Properties.Resources._7,
               global::AForgeImaging.Properties.Resources._8,
               global::AForgeImaging.Properties.Resources._9,
               global::AForgeImaging.Properties.Resources.dot
             };

            ExhaustiveTemplateMatching templateMatching = new ExhaustiveTemplateMatching(0.9f);

            float max = 0;
            int index = 0;
            for (int i = 0; i < files.Length; i++)
            {
                Bitmap newb = imgCut( files[i]);
                var compare = templateMatching.ProcessImage(machImg, newb);
                if (compare.Length > 0 && compare[0].Similarity > max)
                {
                    //记录下最相似的
                    max = compare[0].Similarity;
                    index = i;

                }

            }

            label3.Text = index.ToString();
        }
예제 #27
0
        /// <summary>
        /// Scans rank of face cards
        /// </summary>
        /// <param name="cardImage"></param>
        /// <returns></returns>
        private Rank ScanFaceRank(Bitmap bmp)
        {
            //Initiliaze template matching class with 0.75 threshold

            Rank rank = Rank.Ace;

            ExhaustiveTemplateMatching tempMatch = new ExhaustiveTemplateMatching(0.0f);


            TemplateMatch[] matchings = tempMatch.ProcessImage(bmp, j);
            if (matchings[0].Similarity > 0.85)
            {
                rank = Rank.Queen;
                return rank;
            }


            matchings = tempMatch.ProcessImage(bmp, j);
            if (matchings[0].Similarity > 0.83)
            {
                rank = Rank.Jack;
                return rank;
            }

            matchings = tempMatch.ProcessImage(bmp, k);
            if (matchings[0].Similarity > 0.80)
            {

                rank = Rank.King;
                return rank;
            }

            matchings = tempMatch.ProcessImage(bmp, q);




            return rank;



            /*
                        int jlength, klength;
                        jlength = templateMatchin.ProcessImage(bmp, j).Length;
            
                        if (templateMatchin.ProcessImage(bmp, j).Length > 0) //If Jack template matches
                            rank = Rank.Jack;

                        if (templateMatchin.ProcessImage(bmp, k).Length > 0)//If King template matches
                            rank = Rank.King;
                        if (templateMatchin.ProcessImage(bmp, q).Length > 0)//If Queen template matches
                            rank = Rank.Queen;*/


        }
예제 #28
0
        public static bool UpdateHeroMounted(CurrentGameState state)
        {
            if (ShouldBringToFront) ControlInput.BringHeroesToFront();
            Bitmap src;
            Bitmap sourceImage;
            Bitmap croppedImage;

            try
            {
                src = GrabScreenGDI(gameScreen);
                sourceImage = ChangePixelFormat(src, PixelFormat.Format24bppRgb);

                Tools.Cropper.Rectangle = new Rectangle(0, 700, 70, 250);
                croppedImage = Tools.Cropper.Apply(sourceImage);

                var patternFinder = new ExhaustiveTemplateMatching(0.9f);

                var matches1 = patternFinder.ProcessImage(croppedImage, templateMounted);

                if (matches1.Length > 0)
                {
                    state.Me.IsMounted = true;
                }
                state.Me.IsMounted = false;
                src.Dispose();
                sourceImage.Dispose();
                croppedImage.Dispose();
            }
            catch (Exception e)
            {
            }
            finally
            {
            }
            return false;
        }
예제 #29
0
        private ButtonTip ScanButtonTip(Bitmap bmp)
        {
            //Initiliaze template matching class with 0.75 threshold
            ExhaustiveTemplateMatching templateMatchin = new ExhaustiveTemplateMatching(0.9f);
            var tip = ButtonTip.NOT_RECOGNIZED;
            if (bmp.Size.Height <= Resources.chk.Size.Height || bmp.Size.Width <= Resources.chk.Size.Width)
            {
                return tip;
            }

            if (templateMatchin.ProcessImage(bmp, Resources.chk).Length > 0) //If Jack template matches
                tip = ButtonTip.Check;
            if (templateMatchin.ProcessImage(bmp, Resources.fld).Length > 0)//If King template matches
                tip = ButtonTip.Fold;
            if (templateMatchin.ProcessImage(bmp, Resources.bt).Length > 0)//If Queen template matches
                tip = ButtonTip.Bet;
            if (templateMatchin.ProcessImage(bmp, Resources.cll).Length > 0)//If Queen template matches
                tip = ButtonTip.Call;
            if (templateMatchin.ProcessImage(bmp, Resources.rz).Length > 0)//If Queen template matches
                tip = ButtonTip.Raise;

            return tip;
        }
예제 #30
0
        /// <summary>
        /// Scans rank of face cards
        /// </summary>
        /// <param name="cardImage"></param>
        /// <returns></returns>
        private Rank ScanRank(Bitmap bmp)
        {
            //Initiliaze template matching class with 0.75 threshold
            ExhaustiveTemplateMatching templateMatchin = new ExhaustiveTemplateMatching(0.99f);
            Rank rank = Rank.NOT_RECOGNIZED;

            if (templateMatchin.ProcessImage(bmp, j).Length > 0) //If Jack template matches
                rank = Rank.Jack;
            if (templateMatchin.ProcessImage(bmp, k).Length > 0)//If King template matches
                rank = Rank.King;
            if (templateMatchin.ProcessImage(bmp, q).Length > 0)//If Queen template matches
                rank = Rank.Queen;

            if (templateMatchin.ProcessImage(bmp, Resources.A).Length > 0)//If Queen template matches
                rank = Rank.Ace;
            if (templateMatchin.ProcessImage(bmp, Resources._2).Length > 0)//If Queen template matches
                rank = Rank.Two;
            if (templateMatchin.ProcessImage(bmp, Resources._3).Length > 0)//If Queen template matches
                rank = Rank.Three;
            if (templateMatchin.ProcessImage(bmp, Resources._4).Length > 0)//If Queen template matches
                rank = Rank.Four;
            if (templateMatchin.ProcessImage(bmp, Resources._5).Length > 0)//If Queen template matches
                rank = Rank.Five;
            if (templateMatchin.ProcessImage(bmp, Resources._6).Length > 0)//If Queen template matches
                rank = Rank.Six;
            if (templateMatchin.ProcessImage(bmp, Resources._7).Length > 0)//If Queen template matches
                rank = Rank.Seven;
            if (templateMatchin.ProcessImage(bmp, Resources._8).Length > 0)//If Queen template matches
                rank = Rank.Eight;
            if (templateMatchin.ProcessImage(bmp, Resources._9).Length > 0)//If Queen template matches
                rank = Rank.Nine;
            if (templateMatchin.ProcessImage(bmp, Resources._10).Length > 0)//If Queen template matches
                rank = Rank.Ten;
            return rank;
        }
예제 #31
0
        private void Detect(object sender, DoWorkEventArgs e)
        {
            while (true)
            {
                using (Graphics g = Graphics.FromImage(current))
                {
                    Mouse.Click(new Point(bounds.Location.X + 10, bounds.Location.Y + 10), new[] { Mouse.MouseEvent.LeftDown, Mouse.MouseEvent.LeftUp });
                    g.CopyFromScreen(bounds.Location, Point.Empty, bounds.Size);

                    lock (locker)
                    {
                        tasks.Clear();
                    }

                    ExhaustiveTemplateMatching actionMatching = new ExhaustiveTemplateMatching(0.85f);
                    BlobCounter actions = new BlobCounter { FilterBlobs = true, MinWidth =  30, MinHeight = 30, MaxWidth =  42, MaxHeight = 42 };
                    BlobCounter buttons = new BlobCounter { FilterBlobs = true, MinWidth = 140, MinHeight = 40, MaxWidth = 175, MaxHeight = 50 };
                    Bitmap yellowOnly = keepYellowOnly.Apply(current);
                    actions.ProcessImage(yellowOnly);
                    buttons.ProcessImage(yellowOnly);

                    ////new ColorFiltering
                    ////{
                    ////    Red = new IntRange(00, 75),
                    ////    Green = new IntRange(00, 75),
                    ////    Blue = new IntRange(00, 75),
                    ////    FillColor = new RGB(Color.White),
                    ////    FillOutsideRange = true
                    ////}.ApplyInPlace(current);
                    ////numbers.ProcessImage(current);

                    //int i = 0;

                    ////keepYellowOnly.ApplyInPlace(current);   // output image with color filter applied
                    ////foreach (Blob blob in buttons.GetObjectsInformation().Concat(actions.GetObjectsInformation()))
                    ////    if (!templates.Where(t => t.Icon.Height <= blob.Rectangle.Height && t.Icon.Width <= blob.Rectangle.Width)
                    ////                    .Any(t => exhaustive.ProcessImage(current, t.Icon, blob.Rectangle).Length == 0))
                    //foreach (Blob blob in buttons.GetObjectsInformation().Concat(actions.GetObjectsInformation()))
                    //    {
                    //        using (Bitmap icon = new Bitmap(blob.Rectangle.Width, blob.Rectangle.Height))
                    //        using (Graphics g1 = Graphics.FromImage(icon))
                    //        {
                    //            icon.SetResolution(current.HorizontalResolution, current.VerticalResolution);
                    //            g1.DrawImage(current, 0, 0, blob.Rectangle, GraphicsUnit.Pixel);
                    //            icon.Save(String.Format(@"C:\Users\Rubens\Desktop\simcity\{0}.jpg", ++i), ImageFormat.Jpeg);
                    //        }
                    //        g.FillRectangle(new SolidBrush(Color.FromArgb(128, Color.Yellow)), blob.Rectangle);
                    //    }
                    ////current.Save(@"C:\Users\Rubens\Desktop\newIconXXX.png");

                    #region Identify actions and buttons

                    foreach (Blob blob in actions.GetObjectsInformation().Concat(
                                          buttons.GetObjectsInformation()))
                    {
                        foreach (var template in templates.Where(t => t.Icon.Height <= blob.Rectangle.Height && t.Icon.Width <= blob.Rectangle.Width))
                        foreach (var match in actionMatching.ProcessImage(current, template.Icon, blob.Rectangle))
                        {
                            Rectangle target = CalculateOffset(match.Rectangle, template.Offset);
                            g.FillRectangle(new SolidBrush(Color.FromArgb(128, template.Color)), match.Rectangle);
                            g.FillRectangle(Brushes.HotPink, target);   // click point

                            if (!template.AutoClick)
                                continue;   // Auto level up?

                            Point location = TranslateScreenCoordinates(target);
                            Task task = new Task
                            {
                                Priority    = template.Priority,
                                Location    = location,
                                MouseEvents = new[] { Mouse.MouseEvent.LeftDown, Mouse.MouseEvent.LeftUp },
                                Type        = template.Name,
                                LastClick   = tracker.ContainsKey(location) ? tracker[location]: DateTime.MinValue,
                                Cost        = template.Cost
                            };

                            lock (locker)
                            {
                                // no existing task on same location
                                if (tasks.All(t => t.Location != task.Location))
                                {
                                    tasks.Add(task);
                                    System.Threading.Monitor.Pulse(locker);
                                }
                            }
                        }
                    }

                    #endregion

                    #region Get application counters

                    int i = 0;
                    BlobCounter counters = new BlobCounter { FilterBlobs = true, MinWidth = 60, MinHeight = 23, MaxWidth = 115, MaxHeight = 25 };
                    ExhaustiveTemplateMatching numberMatching = new ExhaustiveTemplateMatching(0.63f);
                    //new Sharpen().ApplyInPlace(yellowOnly);
                    counters.ProcessImage(yellowOnly);
                    Debug.WriteLine(new string('-', 20));
                    foreach (Blob blob in counters.GetObjectsInformation())
                    {
                        Rectangle adjusted = blob.Rectangle;
                        adjusted.Width += 10;
                        adjusted.X -= 5;

                        using (Bitmap icon = new Bitmap(adjusted.Width, adjusted.Height))
                        using (Graphics g1 = Graphics.FromImage(icon))
                        {
                            icon.SetResolution(current.HorizontalResolution, current.VerticalResolution);
                            g1.DrawImage(current, 0, 0, adjusted, GraphicsUnit.Pixel);
                            //icon.Save(String.Format(@"C:\Users\Rubens\Desktop\simcity\{0}.jpg", ++i), ImageFormat.Jpeg);
                        }
                        g.FillRectangle(new SolidBrush(Color.FromArgb(128, Color.Lime)), blob.Rectangle);

                        Dictionary<int, string> sequence = new Dictionary<int, string>();
                        foreach (var number in numbers)
                        foreach (var match in numberMatching.ProcessImage(current, number.Value, adjusted))
                        {
                            if (!sequence.ContainsKey(match.Rectangle.X))
                                sequence.Add(match.Rectangle.X, number.Key);
                        }

                        Debug.WriteLine(String.Format("{0}{1}", adjusted, String.Join("", sequence.OrderBy(n => n.Key).Select(n => n.Value).ToArray())));
                    }

                    #endregion

                    Refresh();
                }
                Thread.Sleep(TimeSpan.FromSeconds(5));
            }
        }