Beispiel #1
0
        // Conversion from RGB to CIELAB, using illuminant D65.
        public static LabColor ToLab(this Color color)
        {
            // RGB are assumed to be in [0...255] range
            double R = color.R / 255d;
            double G = color.G / 255d;
            double B = color.B / 255d;

            // CIEXYZ coordinates are normalized to [0...1]
            double x = 0.4124564 * R + 0.3575761 * G + 0.1804375 * B;
            double y = 0.2126729 * R + 0.7151522 * G + 0.0721750 * B;
            double z = 0.0193339 * R + 0.1191920 * G + 0.9503041 * B;

            double xRatio = x / XN;
            double yRatio = y / YN;
            double zRatio = z / ZN;

            LabColor result = new LabColor {
                // L is normalized to [0...100]
                L = 116 * XyzToLab(yRatio) - 16,
                a = 500 * (XyzToLab(xRatio) - XyzToLab(yRatio)),
                b = 200 * (XyzToLab(yRatio) - XyzToLab(zRatio))
            };

            return(result);
        }
Beispiel #2
0
        static double GetSingleValue(SortingTask task, int x, int y)
        {
            Color c = task.OriginalImage.GetPixel(x, y);

            switch (task.Metric)
            {
            case SortMetric.Intensity:
                return(c.GetIntensity());

            case SortMetric.Lightness:
                return(c.GetLightness());

            case SortMetric.Value:
                return(Math.Max(c.R, Math.Max(c.G, c.B)));

            case SortMetric.Luma:
                return(c.R * 0.2126 + c.G * 0.7152 + c.B * 0.0722);

            case SortMetric.HslHue:
                return(c.GetHue() / 360d);

            case SortMetric.LabHue: {
                LabColor labC = c.ToLab();
                if (labC.a == 0)
                {
                    return(Math.PI / 2);
                }
                else
                {
                    double lh = Math.Atan2(labC.b, labC.a);
                    if (lh <= 0)
                    {
                        lh = Math.PI * 2 - Math.Abs(lh);
                    }
                    return(lh);
                }
            }

            case SortMetric.Chroma:
                return(c.GetChroma());

            case SortMetric.LabChroma: {
                LabColor labColor = c.ToLab();
                return(Math.Sqrt(labColor.a * labColor.a + labColor.b * labColor.b));
            }


            case SortMetric.HsbSaturation: {
                double chroma = c.GetChroma();
                if (chroma == 0)
                {
                    return(0);
                }
                else
                {
                    return(chroma / c.GetMax());
                }
            }

            case SortMetric.HsiSaturation: {
                double chroma    = c.GetChroma();
                double intensity = c.GetIntensity();
                if (chroma == 0 || intensity == 0)
                {
                    return(0);
                }
                else
                {
                    double m = c.GetMin();
                    return(1 - m / intensity);
                }
            }

            case SortMetric.HslSaturation: {
                double max    = c.GetMax();
                double min    = c.GetMin();
                double chroma = c.GetChroma();
                double L      = c.GetLightness();
                if (chroma == 0 || L == 0 || L == 1)
                {
                    return(0);
                }
                if (L < 0.5)
                {
                    return(chroma / (max + min));
                }
                else
                {
                    return(chroma / (2 - max - min));
                }
            }

            case SortMetric.LabSaturation: {
                LabColor labColor = c.ToLab();
                if (labColor.L < ColorUtil.LinearThreshold)
                {
                    return(0);
                }
                else
                {
                    return(Math.Sqrt(labColor.a * labColor.a + labColor.b * labColor.b) / labColor.L);
                }
            }

            case SortMetric.RedChannel:
                return(c.R);

            case SortMetric.GreenChannel:
                return(c.G);

            case SortMetric.BlueChannel:
                return(c.B);

            case SortMetric.Red:
                return(c.R - Math.Max(c.G, c.B));

            case SortMetric.Green:
                return(c.G - Math.Max(c.R, c.B));

            case SortMetric.Blue:
                return(c.B - Math.Max(c.R, c.G));

            case SortMetric.Cyan:
                return((c.G + c.B) - Math.Max(c.R * 1.5, Math.Abs(c.G - c.B)));

            case SortMetric.Magenta:
                return((c.R + c.B) - Math.Max(c.G * 1.5, Math.Abs(c.R - c.B)));

            case SortMetric.Yellow:
                return((c.R + c.G) - Math.Max(c.B * 1.5, Math.Abs(c.R - c.G)));

            case SortMetric.LabA:
                return(c.ToLab().a);

            case SortMetric.LabB:
                return(c.ToLab().b);

            default:
                throw new ArgumentOutOfRangeException();
            }
        }