Example #1
0
            void searchSolution(Bitmap rgb)
            {
                long start = DateTime.Now.Ticks / 10000;
                Globals.FRAMES_PROCESSED_CIRCULAR++;
                int com_x_sum = 0, com_y_sum = 0, com_x_y_point_count = 0;
                Globals.HARVEST_SIGN_ID++;
                Bitmap bmp = sf.Apply(rgb);

                //if (redTestPoints == null)
                //    calculateRedTestPoints();

                // GeoTransChromosome sampleChromosome = new GeoTransChromosome(bmp, sf, redTestPoints, nonRedTestPoints);
                GeoTransChromosome sampleChromosome = new GeoTransChromosome(bmp, sf, null, this);

                if (population == null || population.BestChromosome == null || population.BestChromosome.Fitness < RS_THRESHOLD - 10)
                {   // fresh population
                    population = new Population(Constants.GA_POPULATION_SIZE,
                        sampleChromosome,
                        sampleChromosome,
                        new EliteSelection()
                        );
                    population.MutationRate = Constants.GA_MUTATION_RATE;
                    population.CrossoverRate = Constants.GA_CROSSOVER_RATE;
                }
                else
                {
                    // half from previous
                    Population tmpPopulation = new Population(Constants.GA_POPULATION_SIZE,
                        sampleChromosome,
                        sampleChromosome,
                        new EliteSelection()
                        );
                    tmpPopulation.MutationRate = Constants.GA_MUTATION_RATE;
                    tmpPopulation.CrossoverRate = Constants.GA_CROSSOVER_RATE;
                    for (int j = 0; j < tmpPopulation.Size / 2; j++)
                    {
                        ((GeoTransChromosome)tmpPopulation[j]).copyContent((GeoTransChromosome)population.BestChromosome);
                    }
                    population = tmpPopulation;
                }

                int i = 0;
                do
                {
                    long start_epoch = DateTime.Now.Ticks / 10000;
                    Globals.FRAMES_PROCESSED_GA_RUNEPOCH++;

                    // run one epoch of genetic algorithm
                    population.RunEpoch();
                    i++;

                    if (Constants.EVALUATE_TIME_ENABLED)
                    {
                        int x = (int)(DateTime.Now.Ticks / 10000 - start_epoch);
                        if (x >= 0)
                        {
                            Globals.TIME_GA_RUNEPOCH_MIN = x < Globals.TIME_GA_RUNEPOCH_MIN ? x : Globals.TIME_GA_RUNEPOCH_MIN;
                            Globals.TIME_GA_RUNEPOCH_MAX = x > Globals.TIME_GA_RUNEPOCH_MAX ? x : Globals.TIME_GA_RUNEPOCH_MAX;
                            Globals.TIME_GA_RUNEPOCH_TOTAL += x;
                        }
                    }
                } while (i < Constants.GA_NUMBER_ITERATIONS);

                GeoTransChromosome bestChromo = null;
                if (population.BestChromosome != null && population.BestChromosome.Fitness > RS_THRESHOLD)
                {
                    bestChromo = (GeoTransChromosome)population.BestChromosome;
                    // int rx = 0, ry = 0, rr = 0;
                    // float rs = 0f;

                    int rx = bestChromo.X, ry = bestChromo.Y, rr = bestChromo.Width;
                    float rs = (float)bestChromo.Fitness;

                    // findCircle(bestChromo.X, bestChromo.Y, bmp, ref rx, ref ry, ref rr, ref rs);
                    if (rs < RS_THRESHOLD || rr==0)
                    {
                        bestChromo = null;
                    }
                    else
                    {
                        rr = (int)(Constants.CAPTURE_RESIZE_CIRCLE * rr);

                        // rr = rr - 2;
                        // Graphics g = Graphics.FromImage(rgb);
                        // g.DrawEllipse(Pens.Cyan, rx - rr, ry - rr, rr * 2, rr * 2);

                        if (Constants.HARVEST_TYPE == Constants.HarvestType.harvestAll || Constants.HARVEST_TYPE == Constants.HarvestType.harvestMisses)
                        {
                            rgb.Save(Constants.base_folder + "hasat\\" + Globals.HARVEST_SIGN_ID + "_0.bmp");
                            bmp.Save(Constants.base_folder + "hasat\\" + Globals.HARVEST_SIGN_ID + "_1.bmp");
                        }

                        rgb = new Crop(new Rectangle(rx - rr,
                                                        ry - rr,
                                                        (rx + rr > rgb.Width - 1 ? rgb.Width - 1 - rx : 2 * rr + 2),
                                                        (ry + rr > rgb.Height - 1 ? rgb.Height - 1 - ry : 2 * rr + 2))).Apply(rgb);
                        rgb = new ResizeBicubic(Constants.SIGN_WIDTH, Constants.SIGN_HEIGHT).Apply(rgb);
                        if (panel != null)
                        {
                            Graphics g = panel.getPanelGraphics();
                            g.DrawRectangle(Pens.Silver, 5, 4, Constants.SIGN_WIDTH, Constants.SIGN_HEIGHT);
                            g.DrawImage(rgb, new Point(5, 4));
                        }

                        if (Constants.HARVEST_TYPE == Constants.HarvestType.harvestAll || Constants.HARVEST_TYPE == Constants.HarvestType.harvestMisses)
                            rgb.Save(Constants.base_folder + "hasat\\" + Globals.HARVEST_SIGN_ID + "_3_" +rs+ ".bmp");

                        rgb = AutoBrightnessProcessor.autoBrightness(rgb, Rectangle.Empty, Constants.AUTOBRIGHTNESS_BASE_LUM);

                        if (Constants.HARVEST_TYPE == Constants.HarvestType.harvestAll || Constants.HARVEST_TYPE == Constants.HarvestType.harvestMisses)
                            rgb.Save(Constants.base_folder + "hasat\\" + Globals.HARVEST_SIGN_ID + "_4.bmp");

                        if (Constants.LABELING_TYPE == Constants.LabelingType.redBlackWhite)
                            rgb = new ColorLabelFilter(new Color[] { Color.FromArgb(255, 0, 0), Color.White, Color.Black }, true).Apply(rgb);
                        else if (Constants.LABELING_TYPE == Constants.LabelingType.blackAndWhite)
                        {
                            int dynamic_gray = 0;
                            rgb = new ColorLabelFilter(new Color[] { Color.White, Color.FromArgb(dynamic_gray, dynamic_gray, dynamic_gray) }, true).Apply(rgb);
                        }

                        /* int start_x = 0, start_y = 0;
                        int y = 0;
                        for (; y < Constants.SIGN_HEIGHT && (start_x + start_y) == 0; y++)
                        {
                            for (int x = 0; x < Constants.SIGN_WIDTH; x++)
                            {
                                Color clr = rgb.GetPixel(x, y);
                                if (clr.R == 0)
                                {
                                    start_x = x;
                                    start_y = y;
                                    break;
                                }
                            }
                        }
                        PointedColorFloodFill filter = new PointedColorFloodFill();
                        filter.Tolerance = Color.FromArgb(0, 0, 0);
                        filter.FillColor = Color.FromArgb(255, 255, 255);
                        filter.StartingPoint = new Point(start_x, start_y);
                        Bitmap rgb_flood_fill = filter.Apply(rgb);

                        bool black_region_found_at_center = false;
                        y = 4 * (Constants.SIGN_HEIGHT / 10);
                        for (int x = 4 * (Constants.SIGN_WIDTH / 10); x < 6 * (Constants.SIGN_WIDTH / 10); x += 2)
                        {
                            Color clr = rgb_flood_fill.GetPixel(x, y);
                            if (clr.R == 0)
                            {
                                black_region_found_at_center = true;
                            }
                        }
                        if (!black_region_found_at_center)
                        {
                            y = 6 * (Constants.SIGN_HEIGHT / 10);
                            for (int x = 4 * (Constants.SIGN_WIDTH / 10); x < 6 * (Constants.SIGN_WIDTH / 10); x += 2)
                            {
                                Color clr = rgb_flood_fill.GetPixel(x, y);
                                if (clr.R == 0)
                                {
                                    black_region_found_at_center = true;
                                    break;
                                }
                            }
                        }
                        if (black_region_found_at_center)
                        {
                            rgb = rgb_flood_fill;
                        }
                        */

                        BitmapData image_data = rgb.LockBits(new Rectangle(0, 0, rgb.Width, rgb.Height), ImageLockMode.ReadWrite, rgb.PixelFormat);
                        int bpp = 3;
                        int nOffset = image_data.Stride - rgb.Width * bpp;
                        System.IntPtr Scan0 = image_data.Scan0;
                        unsafe
                        {
                            byte* p = (byte*)Scan0;
                            for (int y = 0; y < Constants.SIGN_HEIGHT; y++)
                            {
                                // for each pixel
                                for (int x = 0; x < Constants.SIGN_WIDTH; x++, p += bpp)
                                {
                                    if (y >= Constants.SIGN_HEIGHT - 10 || y <= 10 || x >= Constants.SIGN_WIDTH - 10 || x <= 10 ||
                                        Math.Sqrt( (y - Constants.SIGN_HEIGHT / 2) * (y - Constants.SIGN_HEIGHT / 2) + (x - Constants.SIGN_WIDTH / 2) * (x - Constants.SIGN_WIDTH / 2)) > 24
                                        )
                                    {
                                        p[RGB.R] = 255;
                                        p[RGB.G] = 255;
                                        p[RGB.B] = 255;
                                    }
                                    else if (p[RGB.R] == 0)
                                    {
                                        com_x_sum += x;
                                        com_y_sum += y;
                                        com_x_y_point_count++;
                                    }
                                }
                                p += nOffset;
                            }

                        }
                        rgb.UnlockBits(image_data);

                        // Graphics g = Graphics.FromImage(rgb);
                        // g.DrawEllipse(Pens.Green, 32 - 24, 32 - 24, 24 * 2, 24 * 2);

                        if (com_x_y_point_count < 10)
                            bestChromo = null;
                        else if (Constants.HARVEST_TYPE > Constants.HarvestType.noHarvest)
                        {
                            if (Constants.HARVEST_TYPE == Constants.HarvestType.harvestIntoFolder)
                            {
                                string[] signs = Globals.SIGN_IN_FRAME.Split(',');

                                for (int j = 1; j < signs.Length; j++)
                                {
                                    if (!Directory.Exists(Constants.base_folder + "hasat\\" + signs[j]))
                                        Directory.CreateDirectory(Constants.base_folder + "hasat\\" + signs[j]);
                                    lock (Globals.HARVEST_LOCK)
                                    {
                                        rgb.Save(Constants.base_folder + "hasat\\" + signs[j] + "\\" + Globals.HARVEST_SIGN_ID + ".bmp");
                                    }
                                }
                            }
                            else
                            {
                                rgb.Save(Constants.base_folder + "hasat\\" + Globals.HARVEST_SIGN_ID + "_6.bmp");
                            }
                        }

                        gtcBmp = rgb;
                    }
                }

                if (Constants.EVALUATE_TIME_ENABLED)
                {
                    int x = (int)(DateTime.Now.Ticks / 10000 - start);
                    if (x >= 0)
                    {
                        Globals.TIME_CIRCULAR_MIN = x < Globals.TIME_CIRCULAR_MIN ? x : Globals.TIME_CIRCULAR_MIN;
                        Globals.TIME_CIRCULAR_MAX = x > Globals.TIME_CIRCULAR_MAX ? x : Globals.TIME_CIRCULAR_MAX;
                        Globals.TIME_CIRCULAR_TOTAL += x;
                    }
                }

                if (bestChromo != null)
                {
                    if (panel != null)
                    {
                        Graphics g = panel.getPanelGraphics();
                        g.DrawRectangle(Pens.Silver, 5, 74, Constants.SIGN_WIDTH, Constants.SIGN_HEIGHT);
                        g.DrawImage(gtcBmp, new Point(5, 74));
                    }
                    if (msgService != null)
                    {
                        VisionMessage vm = new VisionMessage(gtcBmp.Height, gtcBmp.Width, ByteTools.pixelFormatToBPP(gtcBmp.PixelFormat), gtcBmp);

                        // Center of Mass
                        int com_x = com_x_sum / (com_x_y_point_count == 0 ? 1 : com_x_y_point_count);
                        int com_y = com_y_sum / (com_x_y_point_count == 0 ? 1 : com_x_y_point_count);
                        vm.CoM_X = com_x;
                        vm.CoM_Y = com_y;
                        msgService.sendMsg(vm);
                    }
                }
                else
                {
                    if (Globals.RIGHT_PANEL_SHOWING_STH)
                    {
                        Globals.RIGHT_PANEL_SHOWING_STH = false;
                        // Bitmap img = new Bitmap(160, Constants.IMAGE_HEIGHT, PixelFormat.Format24bppRgb);
                        Graphics g = panel.getPanelGraphics();
                        g.Clear(Color.Silver);

                        /*if (msgService != null)
                        {
                            VisionMessage vm = new VisionMessage(img.Height, img.Width, ByteTools.pixelFormatToBPP(img.PixelFormat), img);
                            vm.bypass = true;
                            msgService.sendMsg(vm);
                        }*/
                    }
                }

                threadRunning = false;
            }
Example #2
0
 public void shift(GeoTransChromosome sg)
 {
     X = (sg.X + 5 * X) / 6;
     Y = (sg.Y + 5 * Y) / 6;
     Width = (sg.Width + 5 * Width) / 6;
 }
Example #3
0
 public void copyContent(GeoTransChromosome gtc)
 {
     X = gtc.X;
     Y = gtc.Y;
     Width = gtc.Width;
 }
Example #4
0
            void searchSolution(Bitmap rgb)
            {
                long start = DateTime.Now.Ticks / 10000;
                Globals.FRAMES_PROCESSED_TRIANGULAR++;
                int com_x_sum = 0, com_y_sum = 0, com_x_y_point_count = 0;
                Globals.HARVEST_SIGN_ID++;

                //if (redTestPoints == null)
                //    calculateRedTestPoints();

                Bitmap bmp = sf.Apply(rgb);
                GeoTransChromosome sampleChromosome = new GeoTransChromosome(bmp, sf, this, null);

                Population tmpPopulation = new Population(Constants.GA_POPULATION_SIZE,
                    sampleChromosome,
                    sampleChromosome,
                    new EliteSelection()
                );
                tmpPopulation.MutationRate = Constants.GA_MUTATION_RATE;
                tmpPopulation.CrossoverRate = Constants.GA_CROSSOVER_RATE;

                if (population == null || population.BestChromosome == null || population.BestChromosome.Fitness < RS_THRESHOLD / 4)
                {
                    // fresh population
                }
                else
                {
                    // half from previous
                    for (int j = 0; j < tmpPopulation.Size / 2; j++)
                    {
                        ((GeoTransChromosome)tmpPopulation[j]).copyContent((GeoTransChromosome)population[j]);
                    }
                }
                population = tmpPopulation;

                Graphics gg = null;

                /*
                Bitmap bmp_x = null;
                if (1!=1)
                {
                    bmp_x = new Bitmap(Constants.IMAGE_WIDTH, Constants.IMAGE_HEIGHT * 2, PixelFormat.Format24bppRgb);
                    gg = Graphics.FromImage(bmp_x);
                    gg.DrawImage(bmp, 0, 0);
                    gg.DrawImage(rgb, 0, Constants.IMAGE_HEIGHT);
                    for (int x = 0; x < population.Size; x++)
                    {
                        GeoTransChromosome chromo = (GeoTransChromosome)population[x];
                        gg.DrawRectangle(Pens.Cyan, chromo.X, chromo.Y, 1, 1);
                    }
                }
                */

                int i = 0;
                do
                {
                    long start_epoch = DateTime.Now.Ticks / 10000;
                    Globals.FRAMES_PROCESSED_GA_RUNEPOCH++;

                    // run one epoch of genetic algorithm
                    population.RunEpoch();

                    if (Constants.EVALUATE_TIME_ENABLED)
                    {
                        int x = (int)(DateTime.Now.Ticks / 10000 - start_epoch);
                        if (x >= 0)
                        {
                            Globals.TIME_GA_RUNEPOCH_MIN = x < Globals.TIME_GA_RUNEPOCH_MIN ? x : Globals.TIME_GA_RUNEPOCH_MIN;
                            Globals.TIME_GA_RUNEPOCH_MAX = x > Globals.TIME_GA_RUNEPOCH_MAX ? x : Globals.TIME_GA_RUNEPOCH_MAX;
                            Globals.TIME_GA_RUNEPOCH_TOTAL += x;
                        }
                    }
                    i++;
                } while (i < Constants.GA_NUMBER_ITERATIONS);

                GeoTransChromosome bestChromo = null;
                float rs = 0;
                if (population.BestChromosome != null && population.BestChromosome.Fitness > RS_THRESHOLD)
                {
                    bestChromo = (GeoTransChromosome)population.BestChromosome;

                    int rx = bestChromo.X, ry = bestChromo.Y, rr = bestChromo.Width;
                    rs = (float)bestChromo.Fitness;

                    if (Constants.HARVEST_TYPE == Constants.HarvestType.harvestAll || Constants.HARVEST_TYPE == Constants.HarvestType.harvestMisses)
                    {
                        rgb.Save(Constants.base_folder + "hasat\\" + Globals.HARVEST_SIGN_ID + "_0.bmp");
                        bmp.Save(Constants.base_folder + "hasat\\" + Globals.HARVEST_SIGN_ID + "_1.bmp");
                    }
                    // findTriangle(bestChromo.X, bestChromo.Y, bmp, ref rx, ref ry, ref rr, ref rs);

                    if (rs < RS_THRESHOLD || rr==0)
                    {
                        if (gg != null)
                        {
                            gg.DrawRectangle(Pens.Red, bestChromo.X - 1, bestChromo.Y - 1, 3, 3);
                            gg.DrawRectangle(Pens.Red, bestChromo.X - bestChromo.Width / 2, bestChromo.Y - bestChromo.Width / 2, bestChromo.Width, bestChromo.Width);
                        }
                        bestChromo = null;
                    }
                    else
                    {
                        rr = (int)(Constants.CAPTURE_RESIZE_TRIANGLE * rr);
                        int xx = (int)(rr * Math.Cos(Math.PI * 30 / 180));  // üçgenin kenarı: 2 . xx
                        int yy = (int)(rr * Math.Sin(Math.PI * 30 / 180));  // üçgenin yüksekliği: 3 . yy

                        int x_left = rx - xx;
                        int y_top = ry - (2 * yy) - ((3*yy)/10);
                        rgb = new Crop(new Rectangle(x_left,
                                                    y_top,
                                                    (x_left + 2 * xx > rgb.Width - 1 ? rgb.Width - 1 - x_left : 2 * xx),
                                                    (y_top + 2 * xx > rgb.Height - 1 ? rgb.Height - 1 - y_top : 2 * xx))).Apply(rgb);
                        if (gg != null)
                        {
                            gg.DrawImage(rgb, 1, Constants.IMAGE_HEIGHT + 1);
                            gg.DrawRectangle(Pens.DarkOrchid, rx - 1, ry - 1, 3, 3);
                            gg.DrawRectangle(Pens.Green, x_left, y_top, rgb.Width, rgb.Height);
                        }

                        rgb = new ResizeBicubic(Constants.SIGN_WIDTH, Constants.SIGN_HEIGHT).Apply(rgb);
                        if (panel != null)
                        {
                            Graphics g = panel.getPanelGraphics();
                            g.DrawRectangle(Pens.Silver, 5, 4, Constants.SIGN_WIDTH, Constants.SIGN_HEIGHT);
                            g.DrawImage(rgb, new Point(5, 4));
                        }

                        if (Constants.HARVEST_TYPE == Constants.HarvestType.harvestAll || Constants.HARVEST_TYPE == Constants.HarvestType.harvestMisses)
                            rgb.Save(Constants.base_folder + "hasat\\" + Globals.HARVEST_SIGN_ID + "_3_" +rs+ ".bmp");
                        rgb = AutoBrightnessProcessor.autoBrightness(rgb, Rectangle.Empty, Constants.AUTOBRIGHTNESS_BASE_LUM);

                        if (Constants.HARVEST_TYPE == Constants.HarvestType.harvestAll || Constants.HARVEST_TYPE == Constants.HarvestType.harvestMisses)
                            rgb.Save(Constants.base_folder + "hasat\\" + Globals.HARVEST_SIGN_ID + "_4.bmp");

                        int dynamic_gray = 0;
                        if (Constants.LABELING_TYPE == Constants.LabelingType.redBlackWhite)
                            rgb = new ColorLabelFilter(new Color[] { Color.FromArgb(255, 0, 0), Color.White, Color.Black }, true).Apply(rgb);
                        else if (Constants.LABELING_TYPE == Constants.LabelingType.blackAndWhite)
                        {
                            rgb = new ColorLabelFilter(new Color[] { Color.White, Color.FromArgb(dynamic_gray, dynamic_gray, dynamic_gray) }, true).Apply(rgb);
                        }
                        if (Constants.HARVEST_TYPE == Constants.HarvestType.harvestAll || Constants.HARVEST_TYPE == Constants.HarvestType.harvestMisses)
                            rgb.Save(Constants.base_folder + "hasat\\" + Globals.HARVEST_SIGN_ID + "_5.bmp");

                        int start_x = 0, start_y = 0;
                        int y = 0;
                        for (; y < Constants.SIGN_HEIGHT && (start_x+start_y)==0; y++)
                        {
                            for (int x = 0; x < Constants.SIGN_WIDTH; x++)
                            {
                                Color clr = rgb.GetPixel(x, y);
                                if (clr.R == 0)
                                {
                                    start_x = x;
                                    start_y = y;
                                    break;
                                }
                            }
                        }
                        PointedColorFloodFill filter = new PointedColorFloodFill();
                        filter.Tolerance = Color.FromArgb(0, 0, 0);
                        filter.FillColor = Color.FromArgb(255, 255, 255);
                        filter.StartingPoint = new Point(start_x, start_y);
                        Bitmap rgb_flood_fill = filter.Apply(rgb);

                        int black_region_found_at_center = 0;
                        y = 4 * (Constants.SIGN_HEIGHT / 10);
                        for (int x = 4 * (Constants.SIGN_WIDTH / 10); x < 6 * (Constants.SIGN_WIDTH / 10); x += 2)
                        {
                            Color clr = rgb_flood_fill.GetPixel(x, y);
                            if (clr.R == 0)
                            {
                                black_region_found_at_center++;
                            }
                        }
                        if (black_region_found_at_center < 8)
                        {
                            y = 6 * (Constants.SIGN_HEIGHT / 10);
                            for (int x = 4 * (Constants.SIGN_WIDTH / 10); x < 6 * (Constants.SIGN_WIDTH / 10); x += 2)
                            {
                                Color clr = rgb_flood_fill.GetPixel(x, y);
                                if (clr.R == 0)
                                {
                                    black_region_found_at_center++;
                                }
                            }
                        }
                        if (black_region_found_at_center >= 5)
                        {
                            rgb = rgb_flood_fill;
                        }

                        BitmapData image_data = rgb.LockBits(new Rectangle(0, 0, rgb.Width, rgb.Height), ImageLockMode.ReadWrite, rgb.PixelFormat);
                        int bpp = 3;
                        int nOffset = image_data.Stride - rgb.Width * bpp;
                        System.IntPtr Scan0 = image_data.Scan0;
                        unsafe
                        {
                            byte* p = (byte*)Scan0;
                            for (y = 0; y < Constants.SIGN_HEIGHT; y++)
                            {
                                // for each pixel
                                for (int x = 0; x < Constants.SIGN_WIDTH; x++, p += bpp)
                                {
                                    if (y >= Constants.SIGN_HEIGHT - 12 || y <= 14 || x >= Constants.SIGN_WIDTH - 12 || x <= 12
                                        ||
                                             (x <= Constants.SIGN_WIDTH / 2 && y <= (Constants.SIGN_HEIGHT) - 2 * x + 8)
                                        || (x > Constants.SIGN_WIDTH / 2 && y <= 2 * (x - Constants.SIGN_HEIGHT / 2) + 8)

                                        )
                                    {
                                        p[RGB.R] = 255;
                                        p[RGB.G] = 255;
                                        p[RGB.B] = 255;
                                    }
                                    else if (p[RGB.R] == 0)
                                    {
                                        com_x_sum += x;
                                        com_y_sum += y;
                                        com_x_y_point_count++;
                                    }
                                }
                                p += nOffset;
                            }
                        }
                        rgb.UnlockBits(image_data);

                        if (com_x_y_point_count < 10)
                            bestChromo = null;
                        else if (Constants.HARVEST_TYPE > Constants.HarvestType.noHarvest)
                        {
                            if (Constants.HARVEST_TYPE == Constants.HarvestType.harvestIntoFolder)
                            {
                                string[] signs = Globals.SIGN_IN_FRAME.Split(',');

                                for (int j = 1; j < signs.Length; j++)
                                {
                                    if (!Directory.Exists(Constants.base_folder + "hasat\\" + signs[j]))
                                        Directory.CreateDirectory(Constants.base_folder + "hasat\\" + signs[j]);
                                    lock (Globals.HARVEST_LOCK)
                                    {
                                        rgb.Save(Constants.base_folder + "hasat\\" + signs[j] + "\\" + Globals.HARVEST_SIGN_ID + ".bmp");
                                    }
                                }
                            }
                            else
                            {
                                rgb.Save(Constants.base_folder + "hasat\\" + Globals.HARVEST_SIGN_ID + "_6.bmp");
                            }
                        }

                        gtcBmp = rgb;
                    }
                }

                if (Constants.EVALUATE_TIME_ENABLED)
                {
                    int x = (int)(DateTime.Now.Ticks / 10000 - start);
                    if (x >= 0)
                    {
                        Globals.TIME_TRIANGLE_MIN = x < Globals.TIME_TRIANGLE_MIN ? x : Globals.TIME_TRIANGLE_MIN;
                        Globals.TIME_TRIANGLE_MAX = x > Globals.TIME_TRIANGLE_MAX ? x : Globals.TIME_TRIANGLE_MAX;
                        Globals.TIME_TRIANGLE_TOTAL += x;
                    }
                }

                if (bestChromo != null)
                {
                    if (panel != null)
                    {
                        Graphics g = panel.getPanelGraphics();
                        g.DrawRectangle(Pens.Silver, 5, 74, Constants.SIGN_WIDTH, Constants.SIGN_HEIGHT);
                        g.DrawImage(gtcBmp, new Point(5, 74));
                    }
                    if (msgService != null)
                    {
                        VisionMessage vm = new VisionMessage(gtcBmp.Height, gtcBmp.Width, ByteTools.pixelFormatToBPP(gtcBmp.PixelFormat), gtcBmp);

                        // Center of Mass
                        vm.CoM_X = com_x_sum / (com_x_y_point_count == 0 ? 1 : com_x_y_point_count);
                        vm.CoM_Y = com_y_sum / (com_x_y_point_count == 0 ? 1 : com_x_y_point_count);
                        msgService.sendMsg(vm);
                    }
                }
                else
                {
                    if (Globals.RIGHT_PANEL_SHOWING_STH)
                    {
                        Globals.RIGHT_PANEL_SHOWING_STH = false;
                        Graphics g = panel.getPanelGraphics();
                        g.Clear(Color.Silver);
                    }
                }

                //if (rs > RS_THRESHOLD)
                //    bmp_x.Save(Constants.base_folder + "hasat\\" + Globals.HARVEST_SIGN_ID + "_" +rs+ "_" +sf.BlueCoeff+ "_" +sf.GreenCoeff+ ".bmp");

                threadRunning = false;
            }