private void ReturnsExpectedValueForKnownInput(double expectedValue, IColorSpace a, IColorSpace b) { var target = new CieDe2000Comparison(); var actualValue = a.Compare(b, target); Assert.IsTrue(expectedValue.BasicallyEqualTo(actualValue), expectedValue + " != " + actualValue); }
private static ConsoleColor GetConsoleColor(Color color) { var bestChoice = ConsoleColor.Black; if (color.A < 50) { return(bestChoice); } var comparer = new CieDe2000Comparison(); var labColor = new Rgb() { R = color.R, G = color.G, B = color.B }.To <Lab>(); var minDiff = Double.MaxValue; foreach (var kvp in _colorMap) { var testColor = new Rgb() { R = kvp.Value.R, G = kvp.Value.G, B = kvp.Value.B }.To <Lab>(); var diff = labColor.Compare(testColor, comparer); if (diff < minDiff) { minDiff = diff; bestChoice = kvp.Key; } } return(bestChoice); }
/// <summary> /// Returns the custom color nearest to the System color input /// </summary> /// <param name="input"></param> /// <returns></returns> public static PColor FindNearestColor(this Color input) { PColor resultMSColor = PColor.WebColors.White; var resultDistance = 255.0; //Create ColorMine RGB and LAB variables for comparisons Rgb inColoRgb = new Rgb { R = input.R, G = input.G, B = input.B }; Lab inColorLab = inColoRgb.To <Lab>(); foreach (var pcolor in PColor.WebColors.All) { var comparerLabColor = new CieDe2000Comparison(); var mineColorRgb = new Rgb { R = pcolor.SystemColor.R, G = pcolor.SystemColor.G, B = pcolor.SystemColor.B }; Lab mineColorLab = mineColorRgb.To <Lab>(); //Comare colors and check if closer than previous closest var currentDistence = inColoRgb.Compare(mineColorLab, comparerLabColor); if (currentDistence == 0) { resultMSColor = pcolor; break; } else if (currentDistence < resultDistance) { resultMSColor = pcolor; resultDistance = currentDistence; } } return(resultMSColor); }
private void CheckColors() { int[] isInField = new int[fld.Colors.Count]; for (int x = 0; x < fld.dominoes.GetLength(0); x++) { for (int y = 0; y < fld.dominoes.GetLength(1); y++) { isInField[fld.dominoes[x, y]]++; } } List <DominoColor> removed = RemovePattern(temp.Colors, isInField); CieDe2000Comparison comp = new CieDe2000Comparison(); List <DominoColor> DuplicateList = new List <DominoColor>(); List <int> ignoreList = new List <int>(); for (int i = 0; i < removed.Count - 1; i++) { if (ignoreList.IndexOf(i) == -1) { for (int j = i + 1; j < removed.Count; j++) { if (comp.Compare((new Rgb() { R = removed[i].rgb.R, G = removed[i].rgb.G, B = removed[i].rgb.B }).To <Lab>(), new Rgb() { R = removed[j].rgb.R, G = removed[j].rgb.G, B = removed[j].rgb.B }.To <Lab>()) < 12) { if (ignoreList.IndexOf(i) == -1) { ignoreList.Add(i); DuplicateList.Add(removed[i]); } if (ignoreList.IndexOf(j) == -1) { ignoreList.Add(j); DuplicateList.Add(removed[j]); } } } } } lvColors.ItemsSource = DuplicateList; }
public void UpdateDominoes() { IColorSpaceComparison comp; switch (m_regression_mode) { case 0: comp = new CmcComparison(); break; case 1: comp = new Cie1976Comparison(); break; case 2: comp = new Cie94Comparison(); break; default: comp = new CieDe2000Comparison(); break; } float scaling_x = (SourceImage.Width - 1) / size_x; float scaling_y = (SourceImage.Height - 1) / size_y; if (!m_allow_stretch) { if (scaling_x > scaling_y) { scaling_x = scaling_y; } else { scaling_y = scaling_x; } } // fix transparency: if image is transparent, background appears black Bitmap notransparency = new Bitmap(SourceImage.Width, SourceImage.Height); Graphics temp = Graphics.FromImage(notransparency); temp.Clear(Color.White); System.Drawing.Imaging.ImageAttributes Att = new System.Drawing.Imaging.ImageAttributes(); Att.SetWrapMode(System.Drawing.Drawing2D.WrapMode.TileFlipXY); temp.DrawImage(SourceImage, new Rectangle(0, 0, SourceImage.Width, SourceImage.Height), 0, 0, SourceImage.Width, SourceImage.Height, GraphicsUnit.Pixel, Att); // image to read from WriteableBitmap pixelsource = BitmapFactory.ConvertToPbgra32Format(ImageHelper.BitmapToBitmapSource(notransparency)); pixelsource.Lock(); System.Windows.Media.Color[] sourceColors = new System.Windows.Media.Color[shapes.Length]; dominoes = new int[shapes.Length]; if (!calculation_mode) { // if source pixel = top left pixel of each domino for (int i = 0; i < shapes.Length; i++) { RectangleF container = shapes[i].GetContainer(scaling_x, scaling_y); try { sourceColors[i] = pixelsource.GetPixel((int)container.X, (int)container.Y); } catch (Exception) { } dominoes[i] = Dithering.Compare(new Rgb() { R = sourceColors[i].R, G = sourceColors[i].G, B = sourceColors[i].B }.To <Lab>(), comp, lab_colors, 0); } } else { // if source pixel is average of region for (int i = 0; i < shapes.Length; i++) { RectangleF container = shapes[i].GetContainer(scaling_x, scaling_y); int r = 0, g = 0, b = 0; int counter = 0; // for loop: each container for (float x_iterator = container.X; x_iterator < container.X + container.Width; x_iterator++) { for (float y_iterator = container.Y; y_iterator < container.Y + container.Width; y_iterator++) { if (shapes[i].IsInside(new PointF(x_iterator, y_iterator), true, scaling_x, scaling_y)) { System.Windows.Media.Color c = pixelsource.GetPixel((int)x_iterator, (int)y_iterator); r += c.R; g += c.G; b += c.B; counter++; } } } sourceColors[i] = System.Windows.Media.Color.FromRgb((byte)(r / counter), (byte)(g / counter), (byte)(b / counter)); // calculates the color of the domino dominoes[i] = Dithering.Compare(new Rgb() { R = sourceColors[i].R, G = sourceColors[i].G, B = sourceColors[i].B }.To <Lab>(), comp, lab_colors, 0); } } }
public void GenerateField(bool update_filters = false) { dominoes = new int[length, height]; System.Drawing.Image i; if (!update_filters) { using (var bmpTemp = new System.Drawing.Bitmap(SourcePath)) { i = new System.Drawing.Bitmap(bmpTemp); } } else { i = ImageHelper.BitmapImageToBitmap(filters.preview); } if (length < 2) { m_length = 2; } if (height < 2) { m_height = 2; } System.Drawing.Bitmap thumb = new System.Drawing.Bitmap(length, height); System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(thumb); graphics.Clear(System.Drawing.Color.White); if (ResizeMode == 0) { graphics.InterpolationMode = InterpolationMode.NearestNeighbor; } if (ResizeMode == 1) { graphics.InterpolationMode = InterpolationMode.Bicubic; } if (ResizeMode == 2) { graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; } System.Drawing.Imaging.ImageAttributes attr = new System.Drawing.Imaging.ImageAttributes(); System.Drawing.Imaging.ImageAttributes Att = new System.Drawing.Imaging.ImageAttributes(); Att.SetWrapMode(System.Drawing.Drawing2D.WrapMode.TileFlipXY); graphics.DrawImage(i, new System.Drawing.Rectangle(0, 0, length, height), 0, 0, i.Width, i.Height, System.Drawing.GraphicsUnit.Pixel, Att); //graphics.DrawImage(i, 0, 0, length, height); BitmapImage bitmapImage = ImageHelper.BitmapToBitmapImage(thumb); BitmapSource bitm = new FormatConvertedBitmap(bitmapImage, PixelFormats.Bgr24, null, 0); WriteableBitmap b = BitmapFactory.ConvertToPbgra32Format(bitm); IColorSpaceComparison comp; switch (ColorRegressionMode) { case 0: comp = new CmcComparison(); break; case 1: comp = new Cie1976Comparison(); break; case 2: comp = new Cie94Comparison(); break; default: comp = new CieDe2000Comparison(); break; } Dithering d; switch (DiffusionMode) { case 0: d = new NoDithering(comp, Colors); break; case 1: d = new FloydSteinbergDithering(comp, Colors); break; case 2: d = new JarvisJudiceNinkeDithering(comp, Colors); break; default: d = new StuckiDithering(comp, Colors); break; } dominoes = d.Dither(b, comp); b.Lock(); }
/// <summary> /// Hàm kế thừa từ thư viện AForge.NET. /// Là hàm chính của bộ lọc. /// </summary> /// <param name="sourceData">Ảnh nguồn đầu vào</param> /// <param name="destinationData">Ảnh đầu ra thể hiện các đoạn sau khi được chia. Các đoạn được tô màu ngẫu nhiên</param> protected override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData) { // Có thể cần làm mượt ảnh trước khi tiến hành phân đoạn // sourceData = new GaussianBlur().Apply(sourceData); // Ở đây chúng ta dùng Color LAB để so sánh độ tương đồng của 2 màu khác nhau trong không gian màu RGB // Link tham khảo: // +: http://colormine.org/delta-e-calculator/ // +: http://zschuessler.github.io/DeltaE/learn/ // Sử dụng lớp so sánh từ thư viện ColorMine _logger.Log(string.Format("Ảnh đầu vào: {0}x{1}", sourceData.Width, sourceData.Height)); _logger.Log(string.Format("Tham số: Threshold {0}, Minsize {1}", threshold, minsize)); // Xây dựng đồ thị từ hình ảnh // Mỗi đỉnh đồ thị là 1 điểm ảnh, // Các đỉnh lân cận sẽ có cạnh nối với nhau và // có trọng số là <độ chênh lệnh> giữa 2 điểm ảnh đó // Ở đây sử dụng 4 liền kề // Kết quả sẽ có (Width-1)*(Height-1)*2 cạnh của đồ thị _logger.Log("Bắt đầu phrase 1 - phân hoạch hình ảnh"); var comp = new CieDe2000Comparison(); var items = new QueueItem[(sourceData.Width - 1) * (sourceData.Height - 1) * 2]; var itemCount = 0; for (var y = 0; y < sourceData.Height - 1; y++) { for (var x = 0; x < sourceData.Width - 1; x++) { var color = sourceData.GetPixel(x, y).ToColorMine(); items[itemCount++] = new QueueItem(color.Compare(sourceData.GetPixel(x + 1, y).ToColorMine(), comp), new Point(x, y), new Point(x + 1, y)); items[itemCount++] = new QueueItem(color.Compare(sourceData.GetPixel(x, y + 1).ToColorMine(), comp), new Point(x, y), new Point(x, y + 1)); } } // Xây dựng hàng chờ bao gồm các cạnh sắp xếp theo thứ tự // Trọng số không giảm // Bắt đầu tiến hành tìm cây khung nhỏ nhất (Minimum spanning tree) bằng thuật toán Krusal. _logger.Log(string.Format("Hàng chờ hiện có {0} đối tượng", itemCount)); Array.Sort(items, new QueueItemComparer()); var set = new DisjointSet(sourceData.Width, sourceData.Height); for (var i = 0; i < itemCount; i++) { if (items[i].Val > threshold) { break; } set.Join(items[i].U, items[i].V); } _logger.Log(string.Format("Phrase 1 đã xong, đã tìm thấy {0} đoạn", set.NumSet)); // Tiết hành sát nhập các vùng nhỏ hơn "minSize" với nhau // Cho chất lượng ảnh đầu ra tốt hơn _logger.Log(string.Format("Bắt đầu phrase 2, kết hợp các vùng nhỏ lại")); for (var y = 0; y < sourceData.Height - 1; y++) { for (var x = 0; x < sourceData.Width - 1; x++) { var current = set.Parent(new Point(x, y)); int a = set.Parent(new Point(x + 1, y)), b = set.Parent(new Point(x, y + 1)); if (current != a && (set.SizeOf(current) < minsize || set.SizeOf(a) < minsize)) { set.Join(current, a); } if (current != b && (set.SizeOf(current) < minsize || set.SizeOf(b) < minsize)) { set.Join(current, b); } } } _logger.Log(string.Format("Phrase 2 đã xong, đã tìm thấy {0} đoạn", set.NumSet)); // Bảng màu tô màu các đoạn (super pixels) đã tìm được _logger.Log(string.Format("Bắt đầu tô màu các đoạn")); var colorDict = new Dictionary <int, Color>(); for (var y = 0; y < sourceData.Height; y++) { for (var x = 0; x < sourceData.Width; x++) { var p = set.Parent(new Point(x, y)); Color cl; if (!colorDict.ContainsKey(p)) { cl = RandomColor(); colorDict[p] = cl; } else { cl = colorDict[p]; } destinationData.SetPixel(x, y, cl); } } _logger.Log(string.Format("Phân hoạch ảnh xong")); _logger.Log(new string('-', 80)); }