Example #1
0
 /// <summary>
 /// Gets the CIE-LAB equivalent. If Alpha channel was specified, it will be included.
 /// </summary>
 /// <returns></returns>
 public Color ToColor()
 {
     if (!this._color.HasValue)
     {
         return(LabColor.ToColor(this));
     }
     return(this._color.Value);
 }
Example #2
0
        public LabColor(byte red, byte green, byte blue, byte alpha = 255)
        {
            LabColor labColor = LabColor.FromArgb(red, green, blue, alpha);

            this.L      = labColor.L;
            this.A      = labColor.A;
            this.B      = labColor.B;
            this.Alpha  = labColor.Alpha;
            this._color = Color.FromArgb(alpha, red, green, blue);
        }
Example #3
0
        /// <summary>
        /// This is only for testing. It will create a sample from the image and give it a red hue.
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="stride"></param>
        private static void FindTableClothColor(ref byte[] bytes, int stride)
        {
            //LabColor labColor1 = new LabColor(51f, 2, 2);
            //LabColor labColor2 = new LabColor(50f, 0, 0);

            //float delta = LabColor.FindDeltaE94(labColor1, labColor2);

            int  bytesPerPixel = 4;                                         // each pixel is represented by 4 bytes
            int  imageHeight   = bytes.Length / stride;                     // get the height of the image represented by our bytes
            int  imageWidth    = stride / bytesPerPixel;
            Size quadrantSize  = new Size(imageWidth / 2, imageHeight / 2); // split the image into 4 equally and get size of 1 piece
            // using our quadrant, create a rectangle at the center of the image
            Rectangle sampleRect = new Rectangle(new Point(quadrantSize.Width / 2, quadrantSize.Height / 2), quadrantSize);
            // dictionary which will hold the number of occurrences for each color in our quadrant sample
            Dictionary <Color, int> colorPopularity = new Dictionary <Color, int>();

            // since the table cloth will be the most popular color we need not sample the entire image.
            // to retain some performance we'll sample the center of the image to determine the table cloth color
            // with such a small sample we shouldn't have to worry too much about the color variance caused by highlights and shadows
            // ....hopefully

            for (int yPixelIndex = (sampleRect.Y * stride); yPixelIndex <= (sampleRect.Bottom * stride); yPixelIndex += stride)
            {
                for (int xPixelIndex = sampleRect.X * bytesPerPixel; xPixelIndex <= sampleRect.Right * bytesPerPixel; xPixelIndex += (bytesPerPixel))
                {
                    int offset = xPixelIndex + yPixelIndex;
                    if (offset >= bytes.Length)
                    {
                        break; // this should never happen
                    }
                    byte blue  = bytes[offset];
                    byte green = bytes[++offset];
                    byte red   = bytes[++offset];
                    bytes[offset] = 255;
                    byte  alpha      = bytes[++offset];
                    Color pixelColor = Color.FromArgb(alpha, red, green, blue);

                    if (!colorPopularity.ContainsKey(pixelColor))
                    {
                        colorPopularity.Add(pixelColor, 0);
                    }
                    colorPopularity[pixelColor] += 1;
                }
            }

            Color    popular  = colorPopularity.ToList().OrderByDescending(k => k.Value).First().Key;
            LabColor labColor = new LabColor(popular);
        }
Example #4
0
        /// <summary>
        /// Finds the Delta E(94) of two LabColors
        /// </summary>
        /// <param name="color1"></param>
        /// <param name="color2"></param>
        /// <param name="applicationType"></param>
        /// <remarks>
        /// formula:
        /// http://www.brucelindbloom.com/index.html?Eqn_DeltaE_CIE94.html
        /// summary:
        /// https://opentextbc.ca/graphicdesign/chapter/4-4-lab-colour-space-and-delta-e-measurements/
        /// constants & values breakdown:
        /// https://www.pac.gr/bcm/uploads/a-guide-of-understanding-color-comunication-part-3.pdf
        /// </remarks>
        /// <returns></returns>
        public static float FindDeltaE94(LabColor color1, LabColor color2, Constants.ApplicationType applicationType = Constants.ApplicationType.GraphicArts)
        {
            Constants constants = Constants.Get(applicationType);
            double    K1        = constants.K1;
            double    K2        = constants.K2;
            double    KL        = constants.KL;
            double    KC        = constants.KC; // 1d;
            double    KH        = constants.KH; // 1d;
            // modifying factor to compensate for perceptual distortions in the color space
            double ab = 1d;
            // difference in lightness/darkness value. += lighter | -= darker
            double delta_L = color1.L - color2.L;
            double C1      = Math.Sqrt(Math.Pow(color1.A, 2d) + Math.Pow(color1.B, 2d));
            double C2      = Math.Sqrt(Math.Pow(color2.A, 2d) + Math.Pow(color2.B, 2d));
            // Brightness in chroma. += brighter | -= duller
            double delta_C = C1 - C2;
            // difference on red/green axis. += redder | -= greener
            double delta_a = color1.A - color2.A;
            // difference on yellow/blue axis. += yellower | -= bluer
            double delta_b         = color1.B - color2.B;
            double delta_h_radical = (Math.Pow(delta_a, 2d) + Math.Pow(delta_b, 2d) - Math.Pow(delta_C, 2d));
            // In the calculation of ΔH, the value inside the radical is, in theory, always greater than or equal to zero.
            // However in an actual implementation, it may become a very slightly negative value, due to limited arithmetic precision.
            // Should this occur, the square root will fail.
            // Difference in hue
            double delta_H = Math.Sqrt(delta_h_radical < 0 ? 0 : delta_h_radical);
            double SL      = 1d;
            double SC      = 1d + (K1 * C1);
            double SH      = 1d + (K2 * C1);

            double part1 = Math.Pow(delta_L / (KL * SL), 2d);
            double part2 = Math.Pow(delta_C / (KC * SC), 2d); //  Math.Pow((delta_C * ab) / (KC * SC), 2d);
            double part3 = Math.Pow(delta_H / (KH * SH), 2d); //  Math.Pow((delta_H * ab) / (KH * SH), 2d);
            // Total color difference value
            float delta_E = (float)Math.Sqrt(part1 + part2 + part3);

            return(delta_E);
        }
Example #5
0
        private void calculatedPictureBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (analyzer == null)
            {
                return;
            }
            // prevent out of bound coordinates if picture is smaller than our picture box
            if (e.X > calculatedPictureBox.Image.Width || e.Y > calculatedPictureBox.Image.Height)
            {
                return;
            }

            Color    color    = analyzer.GetColorAtCoordinate(e.Location);
            LabColor labColor = new LabColor(color);

            // testing and sampling data under mouse cursor while over image.
            if (previousLabColor.HasValue)
            {
                float delta = LabColor.FindDeltaE94(previousLabColor.Value, labColor);
                // delta of 10 seems to produce good results in finding objects on the table
                if (delta >= 10)
                {
                    Console.WriteLine();
                    Console.WriteLine("--------------------------------");
                    Console.WriteLine("Color = " + color);
                    Console.WriteLine("Previous Color = " + previousColor);
                    Console.WriteLine("Delta = " + delta);
                }
            }

            Console.WriteLine();
            Console.WriteLine();

            previousColor    = color;
            previousLabColor = labColor;
        }
Example #6
0
 /// <summary>
 /// Converts a Color to its CIE-LAB color equivalent.
 /// If Alpha channel is used, it is preserved but not converted.
 /// </summary>
 /// <param name="color"></param>
 /// <returns></returns>
 public static LabColor FromColor(Color color)
 {
     return(LabColor.FromArgb(color.R, color.G, color.B, color.A));
 }
Example #7
0
 /// <summary>
 /// Converts the CIE-LAB to its Color equivalent. If Alpha channel was specified, it will be included.
 /// </summary>
 /// <returns></returns>
 public static Color ToColor(LabColor labColor)
 {
     // implement conversion and return it
     return(Color.Transparent);
 }