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); }
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); } }
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); }
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); } }
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); }