/// <summary>
        ///     Gets the distance between <paramref name="left"/> and <paramref name="right"/> based on the <see href="http://en.wikipedia.org/wiki/Color_difference#CIEDE2000">CIEDE2000</see> formula.
        /// </summary>
        /// <param name="left">An <see cref="CieLab"/> to compare.</param>
        /// <param name="right">An <see cref="CieLab"/> to compare.</param>
        /// <returns>Score based on similarity, the lower the score the closer that <paramref name="left"/> and <paramref name="right"/> are.</returns>
        public double Distance(CieLab left, CieLab right)
        {
            //Set weighting factors to 1
            const double Kl     = 1.0d;
            const double Kc     = 1.0d;
            const double Kh     = 1.0d;
            var          deltaL = right.L - left.L;
            var          c1ab   = Ciede2000Comparison.Cab(left);
            var          c2ab   = Ciede2000Comparison.Cab(right);
            var          g      = 0.5d * (1 - Ciede2000Comparison.SqrtPow7((c1ab + c2ab) / 2));
            var          a1     = Ciede2000Comparison.A(left, g);
            var          a2     = Ciede2000Comparison.A(right, g);
            var          c1     = Ciede2000Comparison.C(left, a1);
            var          c2     = Ciede2000Comparison.C(right, a2);
            var          deltaC = c2 - c1;
            //Angles in Degree.
            var h1 = Ciede2000Comparison.H(left, a1);
            var h2 = Ciede2000Comparison.H(right, a2);
            //var h_bar = Math.Abs(h1 - h2);
            var deltaH = 2 * Math.Sqrt(c1 * c2) * Math.Sin(Ciede2000Comparison.DeltaHPrime(c1, c2, h1, h2) * Math.PI / 360d);

            // Calculate CIEDE2000
            var cPrimeAverage = (c1 + c2) / 2d;
            var hPrimeAverage = Ciede2000Comparison.HPrimeAverage(c1, c2, h1, h2);
            var sL            = Ciede2000Comparison.SL((left.L + right.L) / 2d);
            var sC            = 1 + .045d * cPrimeAverage;
            var T             = 1 - .17 * Math.Cos(this.DegToRad(hPrimeAverage - 30)) + .24 * Math.Cos(this.DegToRad(hPrimeAverage * 2)) + .32 * Math.Cos(this.DegToRad(hPrimeAverage * 3 + 6)) - .2 * Math.Cos(this.DegToRad(hPrimeAverage * 4 - 63));
            var sH            = 1 + .015 * T * cPrimeAverage;
            var rC            = 2 * Ciede2000Comparison.SqrtPow7(cPrimeAverage);
            var rT            = -Math.Sin(this.DegToRad(2 * (30 * Math.Exp(-Math.Pow((hPrimeAverage - 275) / 25, 2))))) * rC;
            var deltaCResult  = deltaC / (sC * Kc);
            var deltaHResult  = deltaH / (sH * Kh);

            return(Math.Sqrt(Math.Pow(deltaL / (sL * Kl), 2) + Math.Pow(deltaCResult, 2) + Math.Pow(deltaHResult, 2) + rT * deltaCResult * deltaHResult));
        }
        public void Convert_CieLab_to_YCbCr(float l, float a, float b, float y, float cb, float cr)
        {
            // Arrange
            var input    = new CieLab(l, a, b);
            var expected = new YCbCr(y, cb, cr);

            Span <CieLab> inputSpan = new CieLab[5];

            inputSpan.Fill(input);

            Span <YCbCr> actualSpan = new YCbCr[5];

            // Act
            var actual = Converter.ToYCbCr(input);

            Converter.Convert(inputSpan, actualSpan);

            // Assert
            Assert.Equal(expected, actual, ColorSpaceComparer);

            for (int i = 0; i < actualSpan.Length; i++)
            {
                Assert.Equal(expected, actualSpan[i], ColorSpaceComparer);
            }
        }
Esempio n. 3
0
        public void Convert_CieLab_to_Lms(float l, float a, float b, float l2, float m, float s)
        {
            // Arrange
            var input    = new CieLab(l, a, b);
            var expected = new Lms(l2, m, s);

            Span <CieLab> inputSpan = new CieLab[5];

            inputSpan.Fill(input);

            Span <Lms> actualSpan = new Lms[5];

            // Act
            var actual = Converter.ToLms(input);

            Converter.Convert(inputSpan, actualSpan, actualSpan.Length);

            // Assert
            Assert.Equal(expected, actual, ColorSpaceComparer);

            for (int i = 0; i < actualSpan.Length; i++)
            {
                Assert.Equal(expected, actualSpan[i], ColorSpaceComparer);
            }
        }
Esempio n. 4
0
        public void Convert_CieLab_to_LinearRgb(float l, float a, float b, float r, float g, float b2)
        {
            // Arrange
            var input    = new CieLab(l, a, b);
            var expected = new LinearRgb(r, g, b2);

            Span <CieLab> inputSpan = new CieLab[5];

            inputSpan.Fill(input);

            Span <LinearRgb> actualSpan = new LinearRgb[5];

            // Act
            var actual = Converter.ToLinearRgb(input);

            Converter.Convert(inputSpan, actualSpan);

            // Assert
            Assert.Equal(expected, actual, ColorSpaceComparer);

            for (int i = 0; i < actualSpan.Length; i++)
            {
                Assert.Equal(expected, actualSpan[i], ColorSpaceComparer);
            }
        }
Esempio n. 5
0
        public void CieLabToColor()
        {
            // Dark moderate pink.
            CieLab cielab = new CieLab(36.5492f, 33.3173f, -12.0615f);
            Rgba32 color  = cielab;

            Assert.Equal(color.R, 128);
            Assert.Equal(color.G, 64);
            Assert.Equal(color.B, 106);

            // Ochre
            CieLab cielab2 = new CieLab(58.1758f, 27.3399f, 56.8240f);
            Rgba32 color2  = cielab2;

            Assert.Equal(color2.R, 204);
            Assert.Equal(color2.G, 119);
            Assert.Equal(color2.B, 34);

            // Black
            CieLab cielab3 = new CieLab(0, 0, 0);
            Rgba32 color3  = cielab3;

            Assert.Equal(color3.R, 0);
            Assert.Equal(color3.G, 0);
            Assert.Equal(color3.B, 0);

            // Check others.
            //Random random = new Random(0);
            //for (int i = 0; i < 1000; i++)
            //{
            //    Color color4 = new Color((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble());
            //    CieLab cielab4 = color4;
            //    Assert.Equal(color4, (Color)cielab4);
            //}
        }
Esempio n. 6
0
        public void Convert_CieLab_to_Cmyk(float l, float a, float b, float c, float m, float y, float k)
        {
            // Arrange
            var input    = new CieLab(l, a, b);
            var expected = new Cmyk(c, m, y, k);

            Span <CieLab> inputSpan = new CieLab[5];

            inputSpan.Fill(input);

            Span <Cmyk> actualSpan = new Cmyk[5];

            // Act
            var actual = Converter.ToCmyk(input);

            Converter.Convert(inputSpan, actualSpan);

            // Assert
            Assert.Equal(expected, actual, ColorSpaceComparer);

            for (int i = 0; i < actualSpan.Length; i++)
            {
                Assert.Equal(expected, actualSpan[i], ColorSpaceComparer);
            }
        }
        public void Convert_Lch_to_Lab(float l, float c, float h, float l2, float a, float b)
        {
            // Arrange
            var input    = new CieLch(l, c, h);
            var expected = new CieLab(l2, a, b);

            Span <CieLch> inputSpan = new CieLch[5];

            inputSpan.Fill(input);

            Span <CieLab> actualSpan = new CieLab[5];

            // Act
            var actual = Converter.ToCieLab(input);

            Converter.Convert(inputSpan, actualSpan);

            // Assert
            Assert.Equal(expected, actual, ColorSpaceComparer);

            for (int i = 0; i < actualSpan.Length; i++)
            {
                Assert.Equal(expected, actualSpan[i], ColorSpaceComparer);
            }
        }
        public void Convert_CieLab_to_CieLuv(float l, float a, float b, float l2, float u, float v)
        {
            // Arrange
            var input    = new CieLab(l, a, b);
            var expected = new CieLuv(l2, u, v);

            Span <CieLab> inputSpan = new CieLab[5];

            inputSpan.Fill(input);

            Span <CieLuv> actualSpan = new CieLuv[5];

            // Act
            var actual = Converter.ToCieLuv(input);

            Converter.Convert(inputSpan, actualSpan);

            // Assert
            Assert.Equal(expected, actual, ColorSpaceComparer);

            for (int i = 0; i < actualSpan.Length; i++)
            {
                Assert.Equal(expected, actualSpan[i], ColorSpaceComparer);
            }
        }
Esempio n. 9
0
        public void Convert_Hsv_to_CieLab(float h, float s, float v, float l, float a, float b)
        {
            // Arrange
            var input    = new Hsv(h, s, v);
            var expected = new CieLab(l, a, b);

            Span <Hsv> inputSpan = new Hsv[5];

            inputSpan.Fill(input);

            Span <CieLab> actualSpan = new CieLab[5];

            // Act
            var actual = Converter.ToCieLab(input);

            Converter.Convert(inputSpan, actualSpan);

            // Assert
            Assert.Equal(expected, actual, ColorSpaceComparer);

            for (int i = 0; i < actualSpan.Length; i++)
            {
                Assert.Equal(expected, actualSpan[i], ColorSpaceComparer);
            }
        }
        public void Convert_CieXyy_to_CieLab(float x, float y, float yl, float l, float a, float b)
        {
            // Arrange
            var input    = new CieXyy(x, y, yl);
            var expected = new CieLab(l, a, b);

            Span <CieXyy> inputSpan = new CieXyy[5];

            inputSpan.Fill(input);

            Span <CieLab> actualSpan = new CieLab[5];

            // Act
            var actual = Converter.ToCieLab(input);

            Converter.Convert(inputSpan, actualSpan);

            // Assert
            Assert.Equal(expected, actual, ColorSpaceComparer);

            for (int i = 0; i < actualSpan.Length; i++)
            {
                Assert.Equal(expected, actualSpan[i], ColorSpaceComparer);
            }
        }
Esempio n. 11
0
        private static void ComputeColors()
        {
            pixels = new List <ConsolePixel>();

            // char[] chars = { '█', '▓', '▒', '░' };

            int[] rs = { 0, 0, 0, 0, 128, 128, 128, 192, 128, 0, 0, 0, 255, 255, 255, 255 };
            int[] gs = { 0, 0, 128, 128, 0, 0, 128, 192, 128, 0, 255, 255, 0, 0, 255, 255 };
            int[] bs = { 0, 128, 0, 128, 0, 128, 0, 192, 128, 255, 0, 255, 0, 255, 0, 255 };

            for (int i = 0; i < 16; i++)
            {
                for (int j = i + 1; j < 16; j++)
                {
                    var l1 = RGBtoLab(rs[i], gs[i], bs[i]);
                    var l2 = RGBtoLab(rs[j], gs[j], bs[j]);

                    for (int k = 0; k < 4; k++)
                    {
                        var l = CieLab.Combine(l1, l2, (4 - k) / 4.0);

                        pixels.Add(new ConsolePixel
                        {
                            Char      = '█',
                            Forecolor = (ConsoleColor)i,
                            Backcolor = (ConsoleColor)j,
                            Lab       = l
                        });
                    }
                }
            }
        }
Esempio n. 12
0
        public void ColorToCieLab()
        {
            // White
            Rgba32 color  = Rgba32.White;
            CieLab cielab = color;

            Assert.Equal(100, cielab.L, 3);
            Assert.Equal(0.005, cielab.A, 3);
            Assert.Equal(-0.010, cielab.B, 3);

            // Black
            Rgba32 color2  = Rgba32.Black;
            CieLab cielab2 = color2;

            Assert.Equal(0, cielab2.L, 3);
            Assert.Equal(0, cielab2.A, 3);
            Assert.Equal(0, cielab2.B, 3);

            // Gray
            Rgba32 color3  = Rgba32.Gray;
            CieLab cielab3 = color3;

            Assert.Equal(53.585, cielab3.L, 3);
            Assert.Equal(0.003, cielab3.A, 3);
            Assert.Equal(-0.006, cielab3.B, 3);

            // Cyan
            Rgba32 color4  = Rgba32.Cyan;
            CieLab cielab4 = color4;

            Assert.Equal(91.117, cielab4.L, 3);
            Assert.Equal(-48.080, cielab4.A, 3);
            Assert.Equal(-14.138, cielab4.B, 3);
        }
Esempio n. 13
0
        public void Convert_Xyz_to_Lab(float x, float y, float z, float l, float a, float b)
        {
            // Arrange
            var input   = new CieXyz(x, y, z);
            var options = new ColorSpaceConverterOptions {
                WhitePoint = Illuminants.D65, TargetLabWhitePoint = Illuminants.D65
            };
            var converter = new ColorSpaceConverter(options);
            var expected  = new CieLab(l, a, b);

            Span <CieXyz> inputSpan = new CieXyz[5];

            inputSpan.Fill(input);

            Span <CieLab> actualSpan = new CieLab[5];

            // Act
            var actual = converter.ToCieLab(input);

            converter.Convert(inputSpan, actualSpan);

            // Assert
            Assert.Equal(expected, actual, ColorSpaceComparer);

            for (int i = 0; i < actualSpan.Length; i++)
            {
                Assert.Equal(expected, actualSpan[i], ColorSpaceComparer);
            }
        }
Esempio n. 14
0
        /// <summary>
        /// Converts a <see cref="CieLab"/> into a <see cref="LinearRgb"/>
        /// </summary>
        /// <param name="color">The color to convert.</param>
        /// <returns>The <see cref="LinearRgb"/></returns>
        public LinearRgb ToLinearRgb(CieLab color)
        {
            Guard.NotNull(color, nameof(color));

            var xyzColor = this.ToCieXyz(color);

            return(this.ToLinearRgb(xyzColor));
        }
        /// <summary>
        /// Converts a <see cref="CieLab"/> into a <see cref="CieLch"/>
        /// </summary>
        /// <param name="color">The color to convert.</param>
        /// <returns>The <see cref="CieLch"/></returns>
        public CieLch ToCieLch(CieLab color)
        {
            // Adaptation
            CieLab adapted = this.IsChromaticAdaptationPerformed ? this.Adapt(color) : color;

            // Conversion
            return(CieLabToCieLchConverter.Convert(adapted));
        }
Esempio n. 16
0
        /// <summary>
        /// Converts a <see cref="CieLab"/> into a <see cref="YCbCr"/>
        /// </summary>
        /// <param name="color">The color to convert.</param>
        /// <returns>The <see cref="YCbCr"/></returns>
        public YCbCr ToYCbCr(CieLab color)
        {
            Guard.NotNull(color, nameof(color));

            var xyzColor = this.ToCieXyz(color);

            return(this.ToYCbCr(xyzColor));
        }
        /// <summary>
        /// Converts a <see cref="CieLab"/> into a <see cref="Hsl"/>
        /// </summary>
        /// <param name="color">The color to convert.</param>
        /// <returns>The <see cref="Hsl"/></returns>
        public Hsl ToHsl(CieLab color)
        {
            Guard.NotNull(color, nameof(color));

            var xyzColor = this.ToCieXyz(color);

            return(this.ToHsl(xyzColor));
        }
Esempio n. 18
0
        /// <summary>
        /// Converts a <see cref="CieLab"/> into a <see cref="Cmyk"/>
        /// </summary>
        /// <param name="color">The color to convert.</param>
        /// <returns>The <see cref="Cmyk"/></returns>
        public Cmyk ToCmyk(CieLab color)
        {
            Guard.NotNull(color, nameof(color));

            var xyzColor = this.ToCieXyz(color);

            return(this.ToCmyk(xyzColor));
        }
        /// <summary>
        /// Converts a <see cref="CieLab"/> into a <see cref="CieLchuv"/>
        /// </summary>
        /// <param name="color">The color to convert.</param>
        /// <returns>The <see cref="CieLchuv"/></returns>
        public CieLchuv ToCieLchuv(CieLab color)
        {
            Guard.NotNull(color, nameof(color));

            CieXyz xyzColor = this.ToCieXyz(color);

            return(this.ToCieLchuv(xyzColor));
        }
        /// <summary>
        /// Converts a <see cref="CieXyz"/> into a <see cref="CieLchuv"/>
        /// </summary>
        /// <param name="color">The color to convert.</param>
        /// <returns>The <see cref="CieLchuv"/></returns>
        public CieLchuv ToCieLchuv(CieXyz color)
        {
            Guard.NotNull(color, nameof(color));

            CieLab labColor = this.ToCieLab(color);

            return(this.ToCieLchuv(labColor));
        }
        /// <summary>
        /// Converts a <see cref="CieLab"/> into a <see cref="HunterLab"/>
        /// </summary>
        /// <param name="color">The color to convert.</param>
        /// <returns>The <see cref="HunterLab"/></returns>
        public HunterLab ToHunterLab(CieLab color)
        {
            Guard.NotNull(color, nameof(color));

            var xyzColor = this.ToCieXyz(color);

            return(this.ToHunterLab(xyzColor));
        }
Esempio n. 22
0
        /// <summary>
        /// Converts a <see cref="CieLch"/> into a <see cref="CieXyz"/>
        /// </summary>
        /// <param name="color">The color to convert.</param>
        /// <returns>The <see cref="CieXyz"/></returns>
        public CieXyz ToCieXyz(CieLch color)
        {
            // Conversion to Lab
            CieLab labColor = CieLchToCieLabConverter.Convert(color);

            // Conversion to XYZ (incl. adaptation)
            return(this.ToCieXyz(labColor));
        }
        /// <summary>
        /// Converts a <see cref="CieLab"/> into a <see cref="Lms"/>
        /// </summary>
        /// <param name="color">The color to convert.</param>
        /// <returns>The <see cref="Lms"/></returns>
        public Lms ToLms(CieLab color)
        {
            Guard.NotNull(color, nameof(color));

            var xyzColor = this.ToCieXyz(color);

            return(this.ToLms(xyzColor));
        }
Esempio n. 24
0
        private static bool ProcessImage(Bitmap image)
        {
            var bitmap = new Bitmap(image);

            CieLab prevCieLab = null;

            for (int i = 0; i < (int)(bitmap.Width * 0.05); i++)
            {
                for (int j = 0; j < (int)(bitmap.Height * 0.40); j++)
                {
                    var pixel  = bitmap.GetPixel(i, j);
                    var xyz    = pixel.ToXyz();
                    var cieLab = xyz.ToCieLab();
                    if (prevCieLab == null)
                    {
                        prevCieLab = cieLab;
                    }
                    else
                    {
                        var diff = GetDeltaE(prevCieLab, cieLab);
                        if (diff > 5)
                        {
                            return(false);
                        }

                        prevCieLab = cieLab;
                    }
                }
            }

            for (int i = bitmap.Width - (int)(bitmap.Width * 0.05); i < bitmap.Width; i++)
            {
                for (int j = 0; j < (int)(bitmap.Height * 0.40); j++)
                {
                    var pixel  = bitmap.GetPixel(i, j);
                    var xyz    = pixel.ToXyz();
                    var cieLab = xyz.ToCieLab();
                    if (prevCieLab == null)
                    {
                        prevCieLab = cieLab;
                    }
                    else
                    {
                        var diff = GetDeltaE(prevCieLab, cieLab);
                        if (diff > 5)
                        {
                            return(false);
                        }

                        prevCieLab = cieLab;
                    }
                }
            }

            return(true);
        }
Esempio n. 25
0
            public static CieLab Combine(CieLab l1, CieLab l2, double amount)
            {
                var l = l1.L * amount + l2.L * (1 - amount);
                var a = l1.A * amount + l2.A * (1 - amount);
                var b = l1.B * amount + l2.B * (1 - amount);

                return(new CieLab {
                    L = l, A = a, B = b
                });
            }
Esempio n. 26
0
        public void CieLabConstructorAssignsFields()
        {
            const float l      = 75F;
            const float a      = -64F;
            const float b      = 87F;
            var         cieLab = new CieLab(l, a, b);

            Assert.Equal(l, cieLab.L);
            Assert.Equal(a, cieLab.A);
            Assert.Equal(b, cieLab.B);
        }
Esempio n. 27
0
        /// <summary>
        /// Converts a <see cref="CieLab"/> into a <see cref="CieXyz"/>
        /// </summary>
        /// <param name="color">The color to convert.</param>
        /// <returns>The <see cref="CieXyz"/></returns>
        public CieXyz ToCieXyz(CieLab color)
        {
            // Conversion
            CieXyz unadapted = CieLabToCieXyzConverter.Convert(color);

            // Adaptation
            CieXyz adapted = color.WhitePoint.Equals(this.WhitePoint) || !this.IsChromaticAdaptationPerformed
                ? unadapted
                : this.Adapt(unadapted, color.WhitePoint);

            return(adapted);
        }
        public void Convert_Lch_to_Lab(float l, float c, float h, float l2, float a, float b)
        {
            // Arrange
            CieLch input = new CieLch(l, c, h);

            // Act
            CieLab output = Converter.ToCieLab(input);

            // Assert
            Assert.Equal(l2, output.L, FloatRoundingComparer);
            Assert.Equal(a, output.A, FloatRoundingComparer);
            Assert.Equal(b, output.B, FloatRoundingComparer);
        }
        public void Convert_Lab_to_LCHab(float l, float a, float b, float l2, float c, float h)
        {
            // Arrange
            CieLab input = new CieLab(l, a, b);

            // Act
            CieLch output = Converter.ToCieLch(input);

            // Assert
            Assert.Equal(l2, output.L, FloatRoundingComparer);
            Assert.Equal(c, output.C, FloatRoundingComparer);
            Assert.Equal(h, output.H, FloatRoundingComparer);
        }
        /// <summary>
        /// Converts a <see cref="CieLch"/> into a <see cref="CieLab"/>
        /// </summary>
        /// <param name="color">The color to convert.</param>
        /// <returns>The <see cref="CieLab"/></returns>
        public CieLab ToCieLab(CieLch color)
        {
            // Conversion (perserving white point)
            CieLab unadapted = CieLchToCieLabConverter.Convert(color);

            if (!this.IsChromaticAdaptationPerformed)
            {
                return(unadapted);
            }

            // Adaptation
            return(this.Adapt(unadapted));
        }