Пример #1
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="Graphic"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        internal ImageSection Recognize(ref ImageSection Graphic, int x, int y)
        {
            if (mVisualReport != null && mVisDisplay != null)
            {
                Master.sInvokable.Invoke(new Action(mVisDisplay.Show));
                mVisualReport.Start();
            }
            //We've got something, so now scan to find adjacent pixels.
            //Step 1: diagonal, down-right to get a general square shape
            //Step 2: right from each of diag's to fill right side
            //Step 3: down from each of diag's to fill bottom
            //Step 4: around in circles around that, to pick up stragglers
            Func<Color, Point, bool> CheckAdd = (c, p) => { if (this.ValidPixel(c)) { this.AddPixel(p, c); return true; } return false; };
            int DiagMove = 0;
            while (CheckAdd(Graphic.GetPixel(x + DiagMove, y + DiagMove), new Point(x + DiagMove, y + DiagMove)))
                DiagMove++; //This should work on the first pixel, but change to do{}while if it doesn't

            int SubY, SubX;
            for (SubY = 0; SubY <= DiagMove; SubY++) //See the comment on the next line
                for (SubX = SubY + 1; SubX <= DiagMove - SubY && CheckAdd(Graphic.GetPixel(x + SubX, y + SubY), new Point(x + SubX, y + SubY)); SubX++) ; //Note the semicolon: the logical check does all the needed activity

            //This is just a perpendicular copy of above
            for (SubX = 0; SubX <= DiagMove; SubX++)
                for (SubY = SubX + 1; SubY <= DiagMove - SubX && CheckAdd(Graphic.GetPixel(x + SubX, y + SubY), new Point(x + SubX, y + SubY)); SubY++) ; //Note the semicolon: the logical check does all the needed activity

            //Now the tricky part, the round about
            //I'm going to ignore diagonals
            //For each pixel that's been added so far, check all adjacent pixels not checked yet and checkadd them
            //Add the successes to another list and foreach through that one as well. Repeat.
            { //These parenthesis are just to keep these large array variables from lingering too long
                List<Point> LatestAdds = new List<Point>(), AllTested = new List<Point>(), Failed = new List<Point>(); ;
                LatestAdds.AddRange(this.SelectedPixels());
                Point[] CurrentTesting;
                do
                {
                    AllTested.AddRange(LatestAdds);
                    CurrentTesting = LatestAdds.ToArray();
                    LatestAdds = new List<Point>();
                    Point Temp;
                    foreach (Point p in CurrentTesting)
                    {
                        Temp = new Point(p.X - 1, p.Y);
                        if (Temp.X >= 0 && !LatestAdds.Contains(Temp) && !Failed.Contains(Temp) && !AllTested.Contains(Temp))
                        {
                            if (CheckAdd(Graphic.GetPixel(Temp.X, Temp.Y), Temp))
                                LatestAdds.Add(Temp);
                            else Failed.Add(Temp);
                        }
                        Temp = new Point(p.X, p.Y - 1);
                        if (Temp.Y >= 0 && !LatestAdds.Contains(Temp) && !Failed.Contains(Temp) && !AllTested.Contains(Temp))
                        {
                            if (CheckAdd(Graphic.GetPixel(Temp.X, Temp.Y), Temp))
                                LatestAdds.Add(Temp);
                            else Failed.Add(Temp);
                        }
                        Temp = new Point(p.X + 1, p.Y);
                        if (Temp.X < Graphic.Size.Width && !LatestAdds.Contains(Temp) && !Failed.Contains(Temp) && !AllTested.Contains(Temp))
                        {
                            if (CheckAdd(Graphic.GetPixel(Temp.X, Temp.Y), Temp))
                                LatestAdds.Add(Temp);
                            else Failed.Add(Temp);
                        }
                        Temp = new Point(p.X, p.Y + 1);
                        if (Temp.Y < Graphic.Size.Height && !LatestAdds.Contains(Temp) && !Failed.Contains(Temp) && !AllTested.Contains(Temp))
                        {
                            if (CheckAdd(Graphic.GetPixel(Temp.X, Temp.Y), Temp))
                                LatestAdds.Add(Temp);
                            else Failed.Add(Temp);
                        }
                    }
                } while (LatestAdds.Count > 0);
            }

            //
            //Almost done
            //
            if (mVisualReport != null && mVisDisplay != null)
            {
                mVisualReport.Stop();
                Master.sInvokable.Invoke(new Action(mVisDisplay.CloseSafe));
            }
            if (this.mAddedPixels.Count <= Master.sMaster.MinMargin)
                return null;
            this.SubtractFrom(ref Graphic);
#if OUTPUTEACH
            System.IO.FileStream fs = Master.sMaster.GenerateFile("ImgSec " + this.mSize.X + " " + this.mSize.Y + " " + DateTime.Now.ToFileTime() + ".bmp");
            Master.sMaster.OriginalPixels(mAddedPixels.ToArray()).Save(fs, System.Drawing.Imaging.ImageFormat.Bmp);
            fs.Flush();
            fs.Close();
            fs.Dispose();
#endif
            return this.Generate();

            //
            // ALL DONE! One ImageSection down
            //
        }
Пример #2
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ImgSec"></param>
        /// <param name="ColorForgive"></param>
        /// <param name="ColorDetail"></param>
        /// <param name="MinMargin"></param>
        /// <returns></returns>
        internal static Child[] ScanImageSection(ImageSection ImgSec, int ColorForgive, int ColorDetail, int MinMargin, Child Parent = null)
        {
#if GUIOUTPUT
            mScannedPx = 0;
            int MaxSize = ImgSec.Width * ImgSec.Height;
            frmImgSecDisplay DisplayOut = null;
            //DisplayOut.Show();
            //Master.sInvokable.Invoke(Master.sAddable, null => {return new frmImgSecDisplay();}, DisplayOut);
            MakeForm NewDisp = delegate() { return new frmImgSecDisplay(); };
            AssignForm AssDisp = delegate(System.Windows.Forms.Form ToAssign) { DisplayOut = (frmImgSecDisplay)ToAssign; };
            Master.sInvokable.Invoke(Master.sAddable, new object[] { NewDisp, AssDisp });
#endif
            //Break the image into ImageSections
            List<ImageSection> Sections = new List<ImageSection>();
            ImageSectionFactory Factory;
            for (int y = 0; y < ImgSec.Height; y++)
            {
                for (int x = 0; x < ImgSec.Width; x++)
                {
                    if (ImgSec.GetPixel(x, y).A == byte.MaxValue)
                    {
                        Factory = new ImageSectionFactory(new Point(x, y), ColorForgive, ColorDetail
#if GUIOUTPUT
                            ,DisplayOut
#endif
                            );
                        Sections.Add(Factory.Recognize(ref ImgSec, x, y));
#if GUIOUTPUT
                        UpdateDisplay((mScannedPx += Factory.SelectedPixels().Count()), MaxSize, 0);
#endif
                    }
                }
            }

            Sections.RemoveAll(imsec => imsec == null);
            //Figure out if it just selected the whole thing. If so, cancel the scan
            if (Sections.Count == 1 && Sections[0].Size == ImgSec.Size)
                return new Child[0];

            //Figure out which ones of those are too small and should be discounted
            for (int remove = 0; remove < Sections.Count; remove++)
            {
                if (Sections[remove].PixelsUsed().Length <= MinMargin) Sections.RemoveAt(remove);
            }
            Sections.TrimExcess();

            // Once that's done, turn the remaining Image Sections into Children
            Child[] Children = new Child[Sections.Count];
#if MULTITHREAD
            Task<Child>[] Tasks = new Task<Child>[Sections.Count];
#endif
            for (int i = 0; i < Sections.Count; i++)
            {
#if MULTITHREAD
                Tasks[i] = new Task<Child>(s => Child.FromSection((Child)((object[])s)[0], (ImageSection)((object[])s)[1]), new object[]{Parent, Sections[i]});
                Tasks[i].Start();
#else
                Children[i] = Child.FromSection(Parent, Sections[i]);
#endif

#if GUIOUTPUT
                UpdateDisplay(MaxSize, MaxSize, 1);
#endif
            }
#if MULTITHREAD
            try
            {
                while (Tasks.Any(t => !t.IsCompleted)) Tasks.First(t => !t.IsCompleted).Wait();
            }
            catch (NullReferenceException) { }
            for (int i = 0; i < Tasks.Length; i++)
            {
                Children[i] = Tasks[i].Result;
            }
#endif

            return Children;
        }