Пример #1
0
        private double de_1994(LABColor lab1, LABColor lab2)
        {
            var c1 = round_off(Math.Sqrt(lab1.A * lab1.A + lab1.B * lab1.B), 4);
            var c2 = round_off(Math.Sqrt(lab2.A * lab2.A + lab2.B * lab2.B), 4);

            var dc = c1 - c2;

            var dl = round_off(lab1.L - lab2.L, 5);
            var da = round_off(lab1.A - lab2.A, 5);
            var db = round_off(lab1.L - lab2.L, 5);

            var dh = (da * da) + (db * db) - (dc * dc);

            if (dh < 0)
            {
                dh = 0;
            }
            else
            {
                dh = Math.Sqrt(dh);
            }
            var first  = dl;
            var second = dc / (1 + 0.045 * c1);
            var third  = dh / (1 + 0.015 * c1);

            double delta = (Math.Sqrt(first * first + second * second + third * third));

            if (Double.IsNaN(delta))
            {
                throw new Exception("Double is NaN!");
            }
            return(delta);
        }
Пример #2
0
        private bool is_background(Color pixel, int tolerance)
        {
            LABColor tempc = xyz_to_lab(rgb_to_xyz(pixel));

            var whiteCol = new LABColor {
                L = 100.0, A = 23.198503, B = 172.4138
            };

            if (de_1994(tempc, whiteCol) < 1)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #3
0
        private double get_color_standard_deviation(List <Color> colorful_array)
        {
            double L_sum = 0;
            double A_sum = 0;
            double B_sum = 0;

            List <LABColor> lab_colors = new List <LABColor>();

            int c_a_len = colorful_array.Count;

            for (int i = 0; i < c_a_len; i++)
            {
                LABColor tempc = xyz_to_lab(rgb_to_xyz(colorful_array[i]));
                L_sum += tempc.L;
                A_sum += tempc.A;
                B_sum += tempc.B;

                lab_colors.Add(tempc);
            }

            double L_average = L_sum / c_a_len;
            double A_average = A_sum / c_a_len;
            double B_average = B_sum / c_a_len;

            LABColor mean_color = new LABColor {
                L = L_average, A = A_average, B = B_average
            };

            double sum_of_variance_squares = 0;

            foreach (var color in lab_colors)
            {
                sum_of_variance_squares += Math.Pow((de_1994(mean_color, color)), 2);
            }
            double variance = round_off(sum_of_variance_squares / (double)c_a_len, 5);
            double SD       = round_off(Math.Sqrt(variance), 3);

            if (Double.IsNaN(SD))
            {
                throw new Exception("Double is NaN!");
            }
            return(SD);
        }
Пример #4
0
        private bool is_background(List <Color> colorful_array, int tolerance)
        {
            double L_sum = 0;
            double A_sum = 0;
            double B_sum = 0;

            List <LABColor> lab_colors = new List <LABColor>();

            int c_a_len = colorful_array.Count;

            for (int i = 0; i < c_a_len; i++)
            {
                LABColor tempc = xyz_to_lab(rgb_to_xyz(colorful_array[i]));
                L_sum += tempc.L;
                A_sum += tempc.A;
                B_sum += tempc.B;

                lab_colors.Add(tempc);
            }

            double L_average = L_sum / c_a_len;
            double A_average = A_sum / c_a_len;
            double B_average = B_sum / c_a_len;

            LABColor mean_color = new LABColor {
                L = L_average, A = A_average, B = B_average
            };
            var whiteCol = new LABColor {
                L = 100.0, A = 23.198503, B = 172.4138
            };

            if (de_1994(mean_color, whiteCol) < 1)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #5
0
        public List <Coin> GetCoins(Bitmap bmp_image)
        {
            int         m_c_d_sq      = minimum_circle_distance * minimum_circle_distance;
            List <Coin> detectedCoins = new List <Coin>();
            Bitmap      clone_bmp     = (Bitmap)bmp_image.Clone();
            Bitmap      working_image = clone_bmp;
            int         height        = working_image.Height;
            int         width         = working_image.Width;

            int[,] back_fore_mask = new int[height, width];
            LABColor white = xyz_to_lab(rgb_to_xyz(Color.White));

            Console.WriteLine("Generating map...");
            for (int h = 0; h < height; h++)
            {
                for (int w = 0; w < width; w++)
                {
                    if (de_1994(xyz_to_lab(rgb_to_xyz(working_image.GetPixel(w, h))), white) < tolerance)
                    {
                        back_fore_mask[h, w] = 0;
                    }
                    else
                    {
                        back_fore_mask[h, w] = 1;
                    }
                }
            }


            enhance_mask(ref back_fore_mask, width, height, 2);

            Bitmap maskBitmap = new Bitmap(width, height);

            for (int h = 0; h < height; h++)
            {
                for (int w = 0; w < width; w++)
                {
                    if (back_fore_mask[h, w] == 0)
                    {
                        maskBitmap.SetPixel(w, h, Color.Black);
                    }
                    else
                    {
                        maskBitmap.SetPixel(w, h, Color.White);
                    }
                }
            }
            maskBitmap.Save("mask.bmp", System.Drawing.Imaging.ImageFormat.Bmp);

            Console.WriteLine("Map Generated! Finding circles...");

            int max_radius = Math.Min(height, width);
            int radius     = _min_radius;

            for (int row = 0; row < height; row++)
            {
                for (int col = 0; col < width; col++)
                {
                    //var circlePixels = get_pixels_in_circle(col, row, radius, working_image);
                    //double SD = get_color_standard_deviation(circlePixels);
                    int zero_count, one_count;

                    if (back_fore_mask[row, col] == 0)
                    {
                        continue;
                    }

                    count_pixels_in_circle(col, row, radius, back_fore_mask, width, height, out zero_count, out one_count);

                    if (zero_count == 0)
                    {
                        bool ignore_this = false;

                        bool wiggleRoom = true;
                        bool lockX = false, lockY = false;
                        int  tradius = radius, tx = col, ty = row;

                        while (zero_count == 0)
                        {
                            foreach (Coin detected_coin in detectedCoins)
                            {
                                int dx_sq = (tx - detected_coin.xpos) * (tx - detected_coin.xpos);
                                int dy_sq = (ty - detected_coin.ypos) * (ty - detected_coin.ypos);
                                if (dx_sq + dy_sq <= detected_coin.radius * detected_coin.radius)
                                {
                                    ignore_this = true;
                                    break;
                                }
                            }
                            if (ignore_this)
                            {
                                break;
                            }

                            while (wiggleRoom)
                            {
                                int Zup, Zdown, Zleft, Zright;
                                count_pixels_in_circle(tx, ty, tradius, back_fore_mask, width, height, out zero_count, out one_count);
                                if (zero_count == 0)
                                {
                                    break;
                                }
                                //if ((double)zero_count / (double)one_count > 0.01)
                                //{
                                //    ignore_this = true;
                                //    break;
                                //}


                                //wiggle down
                                count_pixels_in_circle(tx, ty + 1, tradius, back_fore_mask, width, height, out Zdown, out one_count);
                                if (Zdown == 0)
                                {
                                    ty++;
                                    lockX = false;
                                }
                                else
                                {
                                    count_pixels_in_circle(tx, ty - 1, tradius, back_fore_mask, width, height, out Zup, out one_count);
                                    if (Zup == 0)
                                    {
                                        ty--;
                                        lockX = false;
                                    }
                                    else
                                    {
                                        if (Zdown >= zero_count && Zup >= zero_count)
                                        {
                                            lockY = true;
                                        }
                                        else
                                        {
                                            lockX = false;
                                            if (Math.Min(Zdown, Zup) == Zdown)
                                            {
                                                ty++;
                                            }
                                            else
                                            {
                                                ty--;
                                            }
                                        }
                                    }
                                }

                                count_pixels_in_circle(tx, ty, tradius, back_fore_mask, width, height, out zero_count, out one_count);
                                if (zero_count == 0)
                                {
                                    break;
                                }

                                count_pixels_in_circle(tx + 1, ty, tradius, back_fore_mask, width, height, out Zright, out one_count);
                                if (Zright == 0)
                                {
                                    tx++;
                                    lockY = false;
                                }
                                else
                                {
                                    count_pixels_in_circle(tx - 1, ty, tradius, back_fore_mask, width, height, out Zleft, out one_count);
                                    if (Zleft == 0)
                                    {
                                        tx--;
                                        lockY = false;
                                    }
                                    else
                                    {
                                        if (Zleft >= zero_count && Zright >= zero_count)
                                        {
                                            lockX = true;
                                        }
                                        else
                                        {
                                            lockY = false;
                                            if (Math.Min(Zleft, Zright) == Zleft)
                                            {
                                                tx--;
                                            }
                                            else
                                            {
                                                tx++;
                                            }
                                        }
                                    }
                                }
                                if (lockX == true && lockY == true)
                                {
                                    wiggleRoom = false;
                                }
                            }
                            tradius++;
                        }
                        if (!ignore_this)
                        {
                            detectedCoins.Add(new Coin {
                                radius = tradius - 1, xpos = tx, ypos = ty
                            });
                            Console.WriteLine("xpos: {0}, ypos: {1}, radius: {2}", tx, ty, tradius);
                        }
                    }
                }
            }
            return(detectedCoins);
        }