/// <summary> /// Compare colors using the Cie94 algorithm. The first color (a) will be used as the reference color. /// </summary> /// <param name="a">Reference color</param> /// <param name="b">Comparison color</param> /// <returns></returns> public double Compare(ColorLab labA, ColorLab labB, bool quick = false) { var deltaL = labA.L - labB.L; var deltaA = labA.A - labB.A; var deltaB = labA.B - labB.B; var c1 = Math.Sqrt(labA.A * labA.A + labA.B * labA.B); var c2 = Math.Sqrt(labB.A * labB.A + labB.B * labB.B); var deltaC = c1 - c2; var deltaH = deltaA * deltaA + deltaB * deltaB - deltaC * deltaC; deltaH = deltaH < 0 ? 0 : Math.Sqrt(deltaH); const double sl = 1.0; const double kc = 1.0; const double kh = 1.0; var sc = 1.0 + Constants.K1 * c1; var sh = 1.0 + Constants.K2 * c1; var deltaLKlsl = deltaL / (Constants.Kl * sl); var deltaCkcsc = deltaC / (kc * sc); var deltaHkhsh = deltaH / (kh * sh); var i = deltaLKlsl * deltaLKlsl + deltaCkcsc * deltaCkcsc + deltaHkhsh * deltaHkhsh; return(i < 0 ? 0 : Math.Sqrt(i)); }
private static System.Drawing.Color getColour(ColorLab c1, ColorLab c2, double ratio) { double ratio2 = 1 - ratio; double L = ((c1.L * ratio2) + (c2.L * ratio)); double a = ((c1.a * ratio2) + (c2.a * ratio)); double b = ((c1.b * ratio2) + (c2.b * ratio)); double alpha = 255 * (1 - (ratio * ratio)); //Console.WriteLine("Lab = " + L.ToString() + "," + a.ToString() + "," + b.ToString()); ColorManagment.ColorConverter Converter = new ColorManagment.ColorConverter(); //create a new instance of a ColorConverter ColorLab lab = new ColorLab(L, a, b); //create new Lab color ColorRGB rgb = Converter.ToRGB(lab); //convert to rgb ColorHSV hsv = Converter.ToHSV(rgb); //conver to HSL //Console.WriteLine("hsl.l = " + hsv.V.ToString()); hsv.V *= alpha / 255.0; //darken rgb = Converter.ToRGB(hsv); //convert to rgb //Console.WriteLine("RGB + " + rgb.R.ToString() + "," + rgb.G.ToString() + "," + rgb.B.ToString()); if (ratio2 == 1.0) { breatheTopPause = true; } if (alpha < 0.02) { return(System.Drawing.Color.FromArgb(0, (int)(rgb.R * 255), (int)(rgb.G * 255), (int)(rgb.B * 255))); } return(System.Drawing.Color.FromArgb(255, (int)(rgb.R * 255), (int)(rgb.G * 255), (int)(rgb.B * 255))); }
/// <summary> /// Calculates the CMC l:c (1984) delta-e value: http://en.wikipedia.org/wiki/Color_difference#CMC_l:c_.281984.29 /// </summary> /// <param name="colorA"></param> /// <param name="colorB"></param> /// <returns></returns> public double Compare(ColorLab aLab, ColorLab bLab, bool quick = false) { var deltaL = aLab.L - bLab.L; var h = MathUtils.RadToDeg(Math.Atan2(aLab.B, aLab.A)); var c1 = Math.Sqrt(aLab.A * aLab.A + aLab.B * aLab.B); var c2 = Math.Sqrt(bLab.A * bLab.A + bLab.B * bLab.B); var deltaC = c1 - c2; var deltaH_2 = (aLab.A - bLab.A) * (aLab.A - bLab.A) + (aLab.B - bLab.B) * (aLab.B - bLab.B) - deltaC * deltaC; var c1_4 = c1 * c1; c1_4 *= c1_4; var t = 164 <= h && h <= 345 ? .56 + Math.Abs(.2 * Math.Cos(MathUtils.DegToRad(h + 168.0))) : .36 + Math.Abs(.4 * Math.Cos(MathUtils.DegToRad(h + 35.0))); var f = Math.Sqrt(c1_4 / (c1_4 + 1900.0)); var sL = aLab.L < 16 ? .511 : (.040975 * aLab.L) / (1.0 + .01765 * aLab.L); var sC = (.0638 * c1) / (1 + .0131 * c1) + .638; var sH = sC * (f * t + 1 - f); var differences = DistanceDivided(deltaL, _lightness * sL) + DistanceDivided(deltaC, _chroma * sC) + deltaH_2 / (sH * sH); return(Math.Sqrt(differences)); }
public ColorLab(double alpha, double l, double a, double b) { ColorLab.check_lab(alpha, l, a, b); this._alpha = alpha; this._l = l; this._a = a; this._b = b; }
public static SectionedLab Min(SectionedLab a, SectionedLab b) => new SectionedLab( ColorLab.Min(a.Left, b.Left), ColorLab.Min(a.Right, b.Right), ColorLab.Min(a.Top, b.Top), ColorLab.Min(a.Bottom, b.Bottom), ColorLab.Min(a.Center, b.Center), ColorLab.Min(a.All, b.All));
protected virtual void ThumbProcessing() { double ld = Math.Log(2); long index = 0; ColorRGB crgb = new ColorRGB(new RGBColorspacesRGB()); ColorLab cl = new ColorLab(); ConversionRoutine routLab = ColorConverter.FindRoutine(crgb, cl); ConversionRoutine routRGB = ColorConverter.FindRoutine(cl, crgb); BitmapEx bmp, bmpE; using (ColorConverter Converter = new ColorConverter()) { for (int i = 0; i < Frames.Count; i++) { double exposure = Math.Log(Frames[i].NewBrightness / Frames[i].AlternativeBrightness, 2); bmp = GetThumb(i, false); bmpE = GetThumbEdited(i, false); unsafe { bmp.LockBits(); bmpE.LockBits(); byte *pix1 = (byte *)bmp.Scan0; byte *pix2 = (byte *)bmpE.Scan0; for (uint y = 0; y < bmp.Height; y++) { for (uint x = 0; x < bmp.Stride; x += bmp.ChannelCount) { index = y * bmp.Stride + x; //LTODO: doesn't calculate correctly crgb.R = pix1[index] / 255d; crgb.G = pix1[index + 1] / 255d; crgb.B = pix1[index + 2] / 255d; Converter.Convert(crgb, cl, routLab); if (exposure < 0) { cl.L = (cl.L < 0.94) ? cl.L : Math.Exp(exposure * ld) * cl.L; } else if (exposure > 0) { cl.L = (cl.L > 0.06) ? cl.L : Math.Exp(exposure * ld) * cl.L; } Converter.Convert(cl, crgb, routRGB); pix2[index] = (byte)(crgb.R * byte.MaxValue); pix2[index + 1] = (byte)(crgb.G * byte.MaxValue); pix2[index + 2] = (byte)(crgb.B * byte.MaxValue); } } bmp.UnlockBits(); bmpE.UnlockBits(); } SetThumbEdited(i, bmpE); MainWorker.ReportProgress(0, new ProgressChangeEventArgs(i * 100 / (Frames.Count - 1), ProgressType.ProcessingThumbs)); } } }
/// <summary> /// Creates a new instance of the <see cref="ColorDifference_CMC"/> class /// </summary> /// <param name="Color1">First color to compare</param> /// <param name="Color2">Second color to compare</param> public ColorDifference_CMC(ColorLab Color1, ColorLab Color2) : base(Color1, Color2) { if (Color1.Space.ReferenceWhite != Whitepoint.D65 || Color2.Space.ReferenceWhite != Whitepoint.D65) { throw new ArgumentException("Color must have a Whitepoint of D65"); } }
private void CompareButton_Click(object sender, EventArgs e) { Color FromColor = GetFromColor(); Color ToColor = GetToColor(); if (FromColor.IsICCcolor && !FromColor.IsPCScolor) { FromColor = Converter.ToICC(FromColor); } if (ToColor.IsICCcolor && !ToColor.IsPCScolor) { ToColor = Converter.ToICC(ToColor); } ColorLCH DIN99From = Converter.ToLCH99(FromColor); ColorLCH DIN99To = Converter.ToLCH99(ToColor); DIN99_E.Text = ColorDifference.GetDeltaE_DIN99((ColorLCH99)DIN99From, (ColorLCH99)DIN99To).ToString("n5", cInfo); DIN99_H.Text = ColorDifference.GetDeltaH_DIN99((ColorLCH99)DIN99From, (ColorLCH99)DIN99To).ToString("n5", cInfo); DIN99_C.Text = ColorDifference.GetDeltaC_DIN99((ColorLCH99)DIN99From, (ColorLCH99)DIN99To).ToString("n5", cInfo); DIN99From = Converter.ToLCH99b(FromColor); DIN99To = Converter.ToLCH99b(ToColor); DIN99b_E.Text = ColorDifference.GetDeltaE_DIN99((ColorLCH99b)DIN99From, (ColorLCH99b)DIN99To).ToString("n5", cInfo); DIN99b_H.Text = ColorDifference.GetDeltaH_DIN99((ColorLCH99b)DIN99From, (ColorLCH99b)DIN99To).ToString("n5", cInfo); DIN99b_C.Text = ColorDifference.GetDeltaC_DIN99((ColorLCH99b)DIN99From, (ColorLCH99b)DIN99To).ToString("n5", cInfo); DIN99From = Converter.ToLCH99c(FromColor); DIN99To = Converter.ToLCH99c(ToColor); DIN99c_E.Text = ColorDifference.GetDeltaE_DIN99((ColorLCH99c)DIN99From, (ColorLCH99c)DIN99To).ToString("n5", cInfo); DIN99c_H.Text = ColorDifference.GetDeltaH_DIN99((ColorLCH99c)DIN99From, (ColorLCH99c)DIN99To).ToString("n5", cInfo); DIN99c_C.Text = ColorDifference.GetDeltaC_DIN99((ColorLCH99c)DIN99From, (ColorLCH99c)DIN99To).ToString("n5", cInfo); DIN99From = Converter.ToLCH99d(FromColor); DIN99To = Converter.ToLCH99d(ToColor); DIN99d_E.Text = ColorDifference.GetDeltaE_DIN99((ColorLCH99d)DIN99From, (ColorLCH99d)DIN99To).ToString("n5", cInfo); DIN99d_H.Text = ColorDifference.GetDeltaH_DIN99((ColorLCH99d)DIN99From, (ColorLCH99d)DIN99To).ToString("n5", cInfo); DIN99d_C.Text = ColorDifference.GetDeltaC_DIN99((ColorLCH99d)DIN99From, (ColorLCH99d)DIN99To).ToString("n5", cInfo); ColorLab LabFrom = Converter.ToLab(FromColor); ColorLab LabTo = Converter.ToLab(ToColor); CIE76_E.Text = ColorDifference.GetDeltaE_CIE76(LabFrom, LabTo).ToString("n5", cInfo); CIE76_H.Text = "N/A"; //CIE76_H.Text = ColorDifference.GetDeltaH_CIE76(LabFrom, LabTo).ToString("n5", cInfo); CIE76_C.Text = "N/A"; //CIE76_C.Text = ColorDifference.GetDeltaC_CIE76(LabFrom, LabTo).ToString("n5", cInfo); CIE94g_E.Text = ColorDifference.GetDeltaE_CIE94(LabFrom, LabTo, CIE94DifferenceMethod.GraphicArts).ToString("n5", cInfo); CIE94t_E.Text = ColorDifference.GetDeltaE_CIE94(LabFrom, LabTo, CIE94DifferenceMethod.Textiles).ToString("n5", cInfo); CIE94g_H.Text = CIE94t_H.Text = ColorDifference.GetDeltaH_CIE94(LabFrom, LabTo).ToString("n5", cInfo); CIE94g_C.Text = CIE94t_C.Text = ColorDifference.GetDeltaC_CIE94(LabFrom, LabTo).ToString("n5", cInfo); CIEDE2000_E.Text = ColorDifference.GetDeltaE_CIEDE2000(LabFrom, LabTo).ToString("n5", cInfo); CIEDE2000_H.Text = "N/A"; //CIEDE2000_H.Text = ColorDifference.GetDeltaH_CIEDE2000(LabFrom, LabTo).ToString("n5", cInfo); CIEDE2000_C.Text = "N/A"; //CIEDE2000_C.Text = ColorDifference.GetDeltaC_CIEDE2000(LabFrom, LabTo).ToString("n5", cInfo); CMC11_E.Text = ColorDifference.GetDeltaE_CMC(LabFrom, LabTo, CMCDifferenceMethod.Perceptibility).ToString("n5", cInfo); CMC21_E.Text = ColorDifference.GetDeltaE_CMC(LabFrom, LabTo, CMCDifferenceMethod.Acceptability).ToString("n5", cInfo); CMC11_H.Text = CMC21_H.Text = ColorDifference.GetDeltaH_CMC(LabFrom, LabTo).ToString("n5", cInfo); CMC11_C.Text = CMC21_C.Text = ColorDifference.GetDeltaC_CMC(LabFrom, LabTo).ToString("n5", cInfo); }
public SectionedLab(ColorLab l, ColorLab r, ColorLab t, ColorLab b, ColorLab c, ColorLab a) { Left = l; Right = r; Top = t; Bottom = b; Center = c; All = a; }
public SectionedLab(ColorLab uniform) { Left = uniform; Right = uniform; Top = uniform; Bottom = uniform; Center = uniform; All = uniform; }
protected override SectionedLabCounts CalcImageData(IEnumerable <PixelPoint> pixels, Point start) { /*int leftCount = 0; * int rightCount = 0; * int topCount = 0; * int bottomCount = 0; * int centerCount = 0; * int allCount = 0;*/ SectionedDouble counts = new SectionedDouble(); SectionedLab area = new SectionedLab(); foreach (PixelPoint p in pixels) { ColorLab color = LabConverter.ToLab(p.Color); if (p.X < left) { area.Left += color; counts.Left++; //leftCount++; } else if (p.X >= right) { area.Right += color; counts.Right++; //rightCount++; } if (p.Y < top) { area.Top += color; counts.Top++; //topCount++; } else if (p.Y >= bottom) { area.Bottom += color; counts.Bottom++; //bottomCount++; } if (p.X >= left && p.X < right && p.Y >= top && p.Y < bottom) { area.Center += color; counts.Center++; //centerCount++; } area.All += color; counts.All++; //allCount++; } return(new SectionedLabCounts(area, counts)); }
public static ColorRgb ToColor(ColorLab lab) { double y = (lab.L + 16.0) / 116.0; double x = lab.A / 500.0 + y; double z = y - lab.B / 200.0; ColorXyz white = XyzConverter.WhiteReference; double x3 = x * x * x; double z3 = z * z * z; ColorXyz xyz = new ColorXyz( white.X * (x3 > XyzConverter.Epsilon ? x3 : (x - 16.0 / 116.0) / 7.787), white.Y * (lab.L > (XyzConverter.Kappa * XyzConverter.Epsilon) ? Math.Pow(((lab.L + 16.0) / 116.0), 3) : lab.L / XyzConverter.Kappa), white.Z * (z3 > XyzConverter.Epsilon ? z3 : (z - 16.0 / 116.0) / 7.787)); return(XyzConverter.ToColor(xyz)); }
protected override SectionedLab CalcFontData(IEnumerable <PixelPoint> pixels) { SectionedDouble counts = new SectionedDouble(); SectionedLab area = new SectionedLab(); double inc = 1; foreach (PixelPoint p in pixels) { inc = p.Color.A / 255d; ColorLab color = LabConverter.ToLab(p.Color) * inc; if (p.X < left) { area.Left += color; counts.Left += inc; //leftCount++; } else if (p.X >= right) { area.Right += color; counts.Right += inc; //rightCount++; } if (p.Y < top) { area.Top += color; counts.Top += inc; //topCount++; } else if (p.Y >= bottom) { area.Bottom += color; counts.Bottom += inc; //bottomCount++; } if (p.X >= left && p.X < right && p.Y >= top && p.Y < bottom) { area.Center += color; counts.Center += inc; //centerCount++; } area.All += color; counts.All += inc; //allCount++; } return((area / counts).ZeroNaNs); }
public ColorXyz(ColorLab lab, RgbWorkingSpace ws) { ColorXyz i = ws.ReferenceWhite.ColorXyz; double delta = 6.0 / 29.0; double fy = (lab.L + 16) / 116.0; double fx = fy + (lab.A / 500.0); double fz = fy - (lab.B / 200.0); double x = (fx > delta) ? i.X * (fx * fx * fx) : (fx - 16.0 / 116.0) * 3 * (delta * delta) * i.X; double y = (fy > delta) ? i.Y * (fy * fy * fy) : (fy - 16.0 / 116.0) * 3 * (delta * delta) * i.Y; double z = (fz > delta) ? i.Z * (fz * fz * fz) : (fz - 16.0 / 116.0) * 3 * (delta * delta) * i.Z; this._alpha = lab.Alpha; this._x = x; this._y = y; this._z = z; }
public override void DeltaH() { var col1 = new ColorLab(18.551095437049, 39.859850965957, 20.274218251707, Whitepoint.D65); var col2 = new ColorLab(25.476424833982, 11.229184491085, 10.108170288432, Whitepoint.D65); using (var cdc = new ColorDifference_CIEDE2000(col1, col2)) { DeltaH(cdc, 0); col1[0] = 36.059942741906; col1[1] = 2.972650137135; col1[2] = -14.453191817134; col2[0] = 50.756107743716; col2[1] = 61.327442426853; col2[2] = 85.37845719472; DeltaH(cdc, 1); } }
public override void DeltaH() { var col1 = new ColorLab(78.012070941279, -109.730946283313, -69.750359159196, Whitepoint.D65); var col2 = new ColorLab(82.925559104386, -33.693161514678, -74.75821654499, Whitepoint.D65); using (var cdc = new ColorDifference_CIE76(col1, col2)) { DeltaH(cdc, 0); col1[0] = 39.920151608493; col1[1] = -41.740163183534; col1[2] = -109.078609910248; col2[0] = 6.683387670984; col2[1] = -121.116973366992; col2[2] = -28.036774207506; DeltaH(cdc, 1); } }
public override void DeltaH() { var col1 = new ColorLab(56.54364036468, -116.587189881288, 0.552391820495, Whitepoint.D65); var col2 = new ColorLab(15.649015053943, 31.881040123352, -114.586263900197, Whitepoint.D65); using (var cdc = new ColorDifference_CMC(col1, col2)) { DeltaH(cdc, 0); col1[0] = 31.310532664093; col1[1] = 81.583387114612; col1[2] = -41.510887980932; col2[0] = 36.092706008857; col2[1] = 83.941777394475; col2[2] = 7.923801354796; DeltaH(cdc, 1); } }
public override void DeltaH() { var col1 = new ColorLab(35.679418652169, 3.282836838408, -40.730857987297, Whitepoint.D65); var col2 = new ColorLab(84.660455880063, -56.01410114533, -17.43254524571, Whitepoint.D65); using (var cdc = new ColorDifference_CIE94(col1, col2)) { DeltaH(cdc, 0); col1[0] = 83.955578740665; col1[1] = -31.540876770993; col1[2] = 41.770289617833; col2[0] = 47.674533462932; col2[1] = -94.988220274094; col2[2] = -11.288529504574; DeltaH(cdc, 1); } }
private static List <Color> GetMainColorsByLab(IEnumerable <ColorCount> colors, int maxCount, double minDiff, double lWeight = 1d) { //List<Tuple<Color, ColorLab>> mainColors = new List<Tuple<Color, ColorLab>>(); List <Color> results = new List <Color>(); List <ColorLab> labs = new List <ColorLab>(); long lastCount = -1; foreach (ColorCount colorCount in colors) { long count = colorCount.Count; Color color = colorCount.Color; ColorLab lab = LabConverter.ToLab(color); lab.L *= lWeight; bool uniqueColorFound = true; foreach (ColorLab labOther in labs) { double score = Cie76Comparison.CompareS(lab, labOther); if (score < minDiff) { uniqueColorFound = false; break; } } if (uniqueColorFound) // color differs by min ammount of HSL so add to response { results.Add(color); labs.Add(lab); if (results.Count == maxCount) { break; } } lastCount = count; } Trace.WriteLine($"Colors Found: {results.Count}/{maxCount}"); return(results); }
private static System.Drawing.Color getColour(ColorLab c1, ColorLab c2, double countup, int speed = 7, int fadespeed = 15) { speed = 21 - speed; double alpha_seed = Math.Sqrt(countup) * fadespeed; if (alpha_seed > 255) { alpha_seed = 255; } int alpha = (int)Math.Max(0, 255 - alpha_seed); double step = 1.0 / speed; double ratio = (countup - 1) * step; if (ratio > 1) { ratio = 1; } if (ratio < 0) { ratio = 0; } double ratio2 = 1 - ratio; double L = ((c1.L * ratio2) + (c2.L * ratio)); double a = ((c1.a * ratio2) + (c2.a * ratio)); double b = ((c1.b * ratio2) + (c2.b * ratio)); //Console.WriteLine("Lab = " + L.ToString() + "," + a.ToString() + "," + b.ToString()); ColorManagment.ColorConverter Converter = new ColorManagment.ColorConverter(); //create a new instance of a ColorConverter ColorLab lab = new ColorLab(L, a, b); //create new Lab color ColorRGB rgb = Converter.ToRGB(lab); //convert to rgb ColorHSV hsv = Converter.ToHSV(rgb); //conver to HSL //Console.WriteLine("hsl.l = " + hsv.V.ToString()); hsv.V *= alpha / 255.0; //darken rgb = Converter.ToRGB(hsv); //convert to rgb //Console.WriteLine("RGB + " + rgb.R.ToString() + "," + rgb.G.ToString() + "," + rgb.B.ToString()); return(System.Drawing.Color.FromArgb(255, (int)(rgb.R * 255), (int)(rgb.G * 255), (int)(rgb.B * 255))); }
private static LabXy[] ConvertToLabXy(ReadOnlySpan <Rgba32> pixels, int width, int height) { LabXy[] labXys = new LabXy[pixels.Length]; //Convert pixels to LabXy for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { int i = x + y * width; var lab = new ColorLab(pixels[i]); labXys[i] = new LabXy() { l = lab.l, a = lab.a, b = lab.b, x = x, y = y }; } } return(labXys); }
public static double CompareS(ColorLab a, ColorLab b, bool quick = false) { double differences = Distance(a.L, b.L) + Distance(a.A, b.A) + Distance(a.B, b.B); return(quick ? differences : Math.Sqrt(differences)); }
private static void DoAnimation() { //return; //WaveTimer.Enabled = false; if (centroids.Count == 0 || Form1.spellText != "") { //LogitechGSDK.LogiLedSetLighting(0, 0, 0); //WaveTimer.Enabled = true; if (Form1.spellText == "" && Form1.useLogitechColours && ((bw_Keysave != null && !bw_Keysave.IsBusy) || (bw_Breathe != null && !bw_Breathe.IsBusy) || (bw_Breathe == null && bw_Keysave == null)) && isAnimated) { //LogitechGSDK.LogiLedSetLighting(0, 0, 0); LogitechGSDK.LogiLedRestoreLighting(); } isAnimated = false; return; } else { isAnimated = true; //calculate the 2 end point colours into LAB space //System.Drawing.Color c1 = Form1.m_startColour; //System.Drawing.Color c2 = Form1.m_endColour; int fadespeed = Form1.m_fadespeed; int gradientspeed = Form1.m_gradientspeed; //ColorManagment.ColorConverter Converter = new ColorManagment.ColorConverter(); //create a new instance of a ColorConverter //ColorRGB rgb1 = new ColorRGB(RGBSpaceName.sRGB, c1.R , c1.G, c1.B ); //create an RGB color //ColorLab lab1 = Converter.ToLab(rgb1); //ColorRGB rgb2 = new ColorRGB(RGBSpaceName.sRGB, c2.R , c2.G, c2.B ); //create an RGB color //ColorLab lab2 = Converter.ToLab(rgb2); //bmp = new Bitmap(21, 6); ColorLab[,] lab1 = new ColorLab[21, 6]; ColorLab[,] lab2 = new ColorLab[21, 6]; for (int x = 0; x < 21; x++) { for (int y = 0; y < 6; y++) { distances[x, y] = double.MaxValue; times[x, y] = int.MaxValue; } } for (int i = 0; i < centroids.Count; i++) { centroid c = centroids[i]; for (int x = 0; x < 21; x++) { for (int y = 0; y < 6; y++) { double distance = Math.Sqrt(((x - c.point.X) * (x - c.point.X) + (y - c.point.Y) * (y - c.point.Y))); distance = Math.Abs(distance) / (Form1.m_distanceFalloff / 2); if (Form1.m_Wave) { distance -= c.countup; distance = Math.Abs(distance); } if ((distance + c.countup) < (Math.Abs(distances[x, y] + times[x, y]))) { distances[x, y] = distance; lab1[x, y] = c.lab1; lab2[x, y] = c.lab2; if (c.countup / 20.0 < times[x, y]) { times[x, y] = c.countup / 20.0; } } } } c.countup++; centroids[i] = c; } bool allBlack = true; try { //bmp = new Bitmap(21, 6); LockBitmap lockBitmap = new LockBitmap(bmp); lockBitmap.LockBits(); for (int x = 0; x < 21; x++) { for (int y = 0; y < 6; y++) { double distance = distances[x, y]; System.Drawing.Color colour = System.Drawing.Color.White; if (Form1.m_Wave == true) { colour = getColour(lab1[x, y], lab2[x, y], distance + times[x, y] + Math.Pow(distance, Form1.m_WaveSpeed), gradientspeed, fadespeed); } else { colour = getColour(lab1[x, y], lab2[x, y], distance + times[x, y], gradientspeed, fadespeed * 10); } lockBitmap.SetPixel(x, y, colour); if (allBlack && (colour.R > 0 || colour.G > 0 || colour.B > 0)) { allBlack = false; } } } lockBitmap.UnlockBits(); } catch { } finally { } byte[] b = Form1.getLEDGridFromBitmap(bmp); //((Form1)Application.OpenForms[0]).pic1.Image = bmp; //bmp.Save(@"C:\temp\heatmap.png"); Debug.WriteLine("set lighting at " + DateTime.Now.Minute.ToString() + ":" + DateTime.Now.Minute.ToString() + ":" + DateTime.Now.Second.ToString() + ":" + DateTime.Now.Millisecond.ToString()); LogitechGSDK.LogiLedSetLightingFromBitmap(b); if (allBlack) { centroids.Clear(); } else if (!Form1.m_Wave) { for (int i = centroids.Count - 1; i >= 0; i--) { try { if (centroids[i].countup / 10 > 255 / fadespeed) { centroids.RemoveAt(i); } } catch { } } } // System.Threading.Thread.Sleep(Form1.m_AnimationSpeed); } //WaveTimer.Enabled = true; }
private void Convert_Button_Click(object sender, EventArgs e) { switch (((Button)sender).Name) { case "RGB_Button": try { if (RGBSpace != RGBSpaceName.ICC) { ColRGB = new ColorRGB(RGBSpace, RGB[0], RGB[1], RGB[2]); } else { ColRGB = new ColorRGB(RGB_ICC, RGB[0], RGB[1], RGB[2]); } Conversion(ColRGB); } catch (FormatException) { MessageBox.Show("Not a number!"); } catch (Exception ex) { MessageBox.Show("Error:" + Environment.NewLine + ex.Message); } break; case "XYZ_Button": try { ColXYZ = new ColorXYZ(XYZwp, XYZ[0], XYZ[1], XYZ[2]); Conversion(ColXYZ); } catch (FormatException) { MessageBox.Show("Not a number!"); } catch (Exception ex) { MessageBox.Show("Error:" + Environment.NewLine + ex.Message); } break; case "Lab_Button": try { ColLab = new ColorLab(Labwp, Lab[0], Lab[1], Lab[2]); Conversion(ColLab); } catch (FormatException) { MessageBox.Show("Not a number!"); } catch (Exception ex) { MessageBox.Show("Error:" + Environment.NewLine + ex.Message); } break; case "Luv_Button": try { ColLuv = new ColorLuv(Luvwp, Luv[0], Luv[1], Luv[2]); Conversion(ColLuv); } catch (FormatException) { MessageBox.Show("Not a number!"); } catch (Exception ex) { MessageBox.Show("Error:" + Environment.NewLine + ex.Message); } break; case "Yxy_Button": try { ColYxy = new ColorYxy(Yxywp, Yxy[0], Yxy[1], Yxy[2]); Conversion(ColYxy); } catch (FormatException) { MessageBox.Show("Not a number!"); } catch (Exception ex) { MessageBox.Show("Error:" + Environment.NewLine + ex.Message); } break; case "LCHab_Button": try { ColLCHab = new ColorLCHab(LCHabwp, LCHab[0], LCHab[1], LCHab[2]); Conversion(ColLCHab); } catch (FormatException) { MessageBox.Show("Not a number!"); } catch (Exception ex) { MessageBox.Show("Error:" + Environment.NewLine + ex.Message); } break; case "LCHuv_Button": try { ColLCHuv = new ColorLCHuv(LCHuvwp, LCHuv[0], LCHuv[1], LCHuv[2]); Conversion(ColLCHuv); } catch (FormatException) { MessageBox.Show("Not a number!"); } catch (Exception ex) { MessageBox.Show("Error:" + Environment.NewLine + ex.Message); } break; case "LCH99_Button": try { ColLCH99 = new ColorLCH99(LCH99[0], LCH99[1], LCH99[2]); Conversion(ColLCH99); } catch (FormatException) { MessageBox.Show("Not a number!"); } catch (Exception ex) { MessageBox.Show("Error:" + Environment.NewLine + ex.Message); } break; case "LCH99b_Button": try { ColLCH99b = new ColorLCH99b(LCH99b[0], LCH99b[1], LCH99b[2]); Conversion(ColLCH99b); } catch (FormatException) { MessageBox.Show("Not a number!"); } catch (Exception ex) { MessageBox.Show("Error:" + Environment.NewLine + ex.Message); } break; case "LCH99c_Button": try { ColLCH99c = new ColorLCH99c(LCH99c[0], LCH99c[1], LCH99c[2]); Conversion(ColLCH99c); } catch (FormatException) { MessageBox.Show("Not a number!"); } catch (Exception ex) { MessageBox.Show("Error:" + Environment.NewLine + ex.Message); } break; case "LCH99d_Button": try { ColLCH99d = new ColorLCH99d(LCH99d[0], LCH99d[1], LCH99d[2]); Conversion(ColLCH99d); } catch (FormatException) { MessageBox.Show("Not a number!"); } catch (Exception ex) { MessageBox.Show("Error:" + Environment.NewLine + ex.Message); } break; case "HSV_Button": try { if (HSVSpace != RGBSpaceName.ICC) { ColHSV = new ColorHSV(HSVSpace, HSV[0], HSV[1], HSV[2]); } else { ColHSV = new ColorHSV(HSV_ICC, HSV[0], HSV[1], HSV[2]); } Conversion(ColHSV); } catch (FormatException) { MessageBox.Show("Not a number!"); } catch (Exception ex) { MessageBox.Show("Error:" + Environment.NewLine + ex.Message); } break; case "HSL_Button": try { if (HSLSpace != RGBSpaceName.ICC) { ColHSL = new ColorHSL(HSLSpace, HSL[0], HSL[1], HSL[2]); } else { ColHSL = new ColorHSL(HSL_ICC, HSL[0], HSL[1], HSL[2]); } Conversion(ColHSL); } catch (FormatException) { MessageBox.Show("Not a number!"); } catch (Exception ex) { MessageBox.Show("Error:" + Environment.NewLine + ex.Message); } break; case "CMY_Button": try { ColCMY = new ColorCMY(CMY_ICC, CMY[0], CMY[1], CMY[2]); Conversion(ColCMY); } catch (FormatException) { MessageBox.Show("Not a number!"); } catch (Exception ex) { MessageBox.Show("Error:" + Environment.NewLine + ex.Message); } break; case "CMYK_Button": try { ColCMYK = new ColorCMYK(CMYK_ICC, CMYK[0], CMYK[1], CMYK[2], CMYK[3]); Conversion(ColCMYK); } catch (FormatException) { MessageBox.Show("Not a number!"); } catch (Exception ex) { MessageBox.Show("Error:" + Environment.NewLine + ex.Message); } break; case "Gray_Button": try { if (Gray_ICC != null) { ColGray = new ColorGray(Gray_ICC, Gray[0]); } else { ColGray = new ColorGray(Gray[0]); } Conversion(ColGray); } catch (FormatException) { MessageBox.Show("Not a number!"); } catch (Exception ex) { MessageBox.Show("Error:" + Environment.NewLine + ex.Message); } break; case "YCbCr_Button": try { if (YCbCrSpace == YCbCrSpaceName.ICC) { ColYCbCr = new ColorYCbCr(YCbCr_ICC, YCbCr[0], YCbCr[1], YCbCr[2]); } else { ColYCbCr = new ColorYCbCr(YCbCrSpace, YCbCr[0], YCbCr[1], YCbCr[2]); } Conversion(ColYCbCr); } catch (FormatException) { MessageBox.Show("Not a number!"); } catch (Exception ex) { MessageBox.Show("Error:" + Environment.NewLine + ex.Message); } break; case "XColor_Button": try { ColX = new ColorX(XColor_ICC, XColor.Take(XColor_Channels).ToArray()); Conversion(ColX); } catch (Exception ex) { MessageBox.Show("Error:" + Environment.NewLine + ex.Message); } break; case "DEF_Button": try { ColDEF = new ColorDEF(DEFwp, DEF[0], DEF[1], DEF[2]); Conversion(ColDEF); } catch (FormatException) { MessageBox.Show("Not a number!"); } catch (Exception ex) { MessageBox.Show("Error:" + Environment.NewLine + ex.Message); } break; case "Bef_Button": try { ColBef = new ColorBef(Befwp, Bef[0], Bef[1], Bef[2]); Conversion(ColBef); } catch (FormatException) { MessageBox.Show("Not a number!"); } catch (Exception ex) { MessageBox.Show("Error:" + Environment.NewLine + ex.Message); } break; case "BCH_Button": try { ColBCH = new ColorBCH(BCHwp, BCH[0], BCH[1], BCH[2]); Conversion(ColBCH); } catch (FormatException) { MessageBox.Show("Not a number!"); } catch (Exception ex) { MessageBox.Show("Error:" + Environment.NewLine + ex.Message); } break; } }
private void Conversion(Color inColor) { Color inColor2 = inColor; if (inColor.IsICCcolor && !inColor.IsPCScolor) { inColor2 = Converter.ToICC(inColor); } if (inColor.Model != ColorModel.CIEXYZ) { ColXYZ = Converter.ToXYZ(inColor2, XYZwp); } if (inColor.Model != ColorModel.CIELab) { ColLab = Converter.ToLab(inColor2, Labwp); } if (inColor.Model != ColorModel.CIELuv) { ColLuv = Converter.ToLuv(inColor2, Luvwp); } if (inColor.Model != ColorModel.CIELCHab) { ColLCHab = Converter.ToLCHab(inColor2, LCHabwp); } if (inColor.Model != ColorModel.CIELCHuv) { ColLCHuv = Converter.ToLCHuv(inColor2, LCHuvwp); } if (inColor.Model != ColorModel.CIEYxy) { ColYxy = Converter.ToYxy(inColor2, Yxywp); } if (inColor.Model != ColorModel.LCH99) { ColLCH99 = Converter.ToLCH99(inColor2); } if (inColor.Model != ColorModel.LCH99b) { ColLCH99b = Converter.ToLCH99b(inColor2); } if (inColor.Model != ColorModel.LCH99c) { ColLCH99c = Converter.ToLCH99c(inColor2); } if (inColor.Model != ColorModel.LCH99d) { ColLCH99d = Converter.ToLCH99d(inColor2); } if (inColor.Model != ColorModel.DEF) { ColDEF = Converter.ToDEF(inColor2); } if (inColor.Model != ColorModel.Bef) { ColBef = Converter.ToBef(inColor2); } if (inColor.Model != ColorModel.BCH) { ColBCH = Converter.ToBCH(inColor2); } if (inColor.Model != ColorModel.RGB) { if (RGBSpace != RGBSpaceName.ICC) { ColRGB = Converter.ToRGB(inColor2, RGBSpace); } else { ColRGB = (ColorRGB)Converter.ToICC(Converter.ToICC_PCS(inColor2, RGB_ICC), RGB_ICC); } } if (inColor.Model != ColorModel.HSV) { if (HSVSpace != RGBSpaceName.ICC) { ColHSV = Converter.ToHSV(inColor2, HSVSpace); } else { ColHSV = (ColorHSV)Converter.ToICC(Converter.ToICC_PCS(inColor2, HSV_ICC), HSV_ICC); } } if (inColor.Model != ColorModel.HSL) { if (HSLSpace != RGBSpaceName.ICC) { ColHSL = Converter.ToHSL(inColor2, HSLSpace); } else { ColHSL = (ColorHSL)Converter.ToICC(Converter.ToICC_PCS(inColor2, HSL_ICC), HSL_ICC); } } if (inColor.Model != ColorModel.CMY && CMY_ICC != null) { ColCMY = (ColorCMY)Converter.ToICC(Converter.ToICC_PCS(inColor2, CMY_ICC), CMY_ICC); } if (inColor.Model != ColorModel.CMYK && CMYK_ICC != null) { ColCMYK = (ColorCMYK)Converter.ToICC(Converter.ToICC_PCS(inColor2, CMYK_ICC), CMYK_ICC); } if (inColor.Model != ColorModel.YCbCr) { if (YCbCrSpace != YCbCrSpaceName.ICC) { ColYCbCr = Converter.ToYCbCr(inColor2, YCbCrSpace); } else { ColYCbCr = (ColorYCbCr)Converter.ToICC(Converter.ToICC_PCS(inColor2, YCbCr_ICC), YCbCr_ICC); } } if (inColor.Model != ColorModel.Gray) { if (CMY_ICC != null) { ColGray = (ColorGray)Converter.ToICC(Converter.ToICC_PCS(inColor2, Gray_ICC), Gray_ICC); } else { ColGray = Converter.ToGray(inColor2); } } if (!IsXColor(inColor.Model) && XColor_ICC != null) { ColX = (ColorX)Converter.ToICC(Converter.ToICC_PCS(inColor2, XColor_ICC), XColor_ICC); } FillFields(); }
/// <summary> /// Creates a new instance of the <see cref="ColorLabDifferenceCalculator"/> class /// </summary> /// <param name="Color1">First color to compare</param> /// <param name="Color2">Second color to compare</param> protected ColorLabDifferenceCalculator(ColorLab Color1, ColorLab Color2) : base(Color1, Color2) { }
protected virtual void ThumbProcessing() { double ld = Math.Log(2); long index = 0; ColorRGB crgb = new ColorRGB(new RGBColorspacesRGB()); ColorLab cl = new ColorLab(); ConversionRoutine routLab = ColorConverter.FindRoutine(crgb, cl); ConversionRoutine routRGB = ColorConverter.FindRoutine(cl, crgb); BitmapEx bmp, bmpE; using (ColorConverter Converter = new ColorConverter()) { for (int i = 0; i < Frames.Count; i++) { double exposure = Math.Log(Frames[i].NewBrightness / Frames[i].AlternativeBrightness, 2); bmp = GetThumb(i, false); bmpE = GetThumbEdited(i, false); unsafe { bmp.LockBits(); bmpE.LockBits(); byte* pix1 = (byte*)bmp.Scan0; byte* pix2 = (byte*)bmpE.Scan0; for (uint y = 0; y < bmp.Height; y++) { for (uint x = 0; x < bmp.Stride; x += bmp.ChannelCount) { index = y * bmp.Stride + x; //LTODO: doesn't calculate correctly crgb.R = pix1[index] / 255d; crgb.G = pix1[index + 1] / 255d; crgb.B = pix1[index + 2] / 255d; Converter.Convert(crgb, cl, routLab); if (exposure < 0) { cl.L = (cl.L < 0.94) ? cl.L : Math.Exp(exposure * ld) * cl.L; } else if (exposure > 0) { cl.L = (cl.L > 0.06) ? cl.L : Math.Exp(exposure * ld) * cl.L; } Converter.Convert(cl, crgb, routRGB); pix2[index] = (byte)(crgb.R * byte.MaxValue); pix2[index + 1] = (byte)(crgb.G * byte.MaxValue); pix2[index + 2] = (byte)(crgb.B * byte.MaxValue); } } bmp.UnlockBits(); bmpE.UnlockBits(); } SetThumbEdited(i, bmpE); MainWorker.ReportProgress(0, new ProgressChangeEventArgs(i * 100 / (Frames.Count - 1), ProgressType.ProcessingThumbs)); } } }
/// <summary> /// Get the WPF color from a Lab color definition /// </summary> private (Color, GraphicColorPrecision) GetColor(ColorLab labColor) { Color color; double L = labColor.L; double a = labColor.A; double b = labColor.B; // http://www.easyrgb.com/en/math.php#text8 double x, y, z, fx, fy, fz; fy = Math.Pow((L + 16.0) / 116.0, 3.0); if (fy < 0.008856) { fy = L / 903.3; } y = fy; if (fy > 0.008856) { fy = Math.Pow(fy, 1.0 / 3.0); } else { fy = 7.787 * fy + 16.0 / 116.0; } fx = a / 500.0 + fy; if (fx > 0.206893) { x = Math.Pow(fx, 3.0); } else { x = (fx - 16.0 / 116.0) / 7.787; } fz = fy - b / 200.0; if (fz > 0.206893) { z = Math.Pow(fz, 3.0); } else { z = (fz - 16.0 / 116.0) / 7.787; } // reference point for D65 x *= 0.950456; y *= 1; z *= 1.088754; // matrix for D65 double rd = 3.240479 * x - 1.537150 * y - 0.498535 * z; double gd = -0.969256 * x + 1.875992 * y + 0.041556 * z; double bd = 0.055648 * x - 0.204043 * y + 1.057311 * z; int ri = (int)((rd * 255.0) + 0.5); int gi = (int)((gd * 255.0) + 0.5); int bi = (int)((bd * 255.0) + 0.5); ri = ri < 0 ? 0 : ri > 255 ? 255 : ri; gi = gi < 0 ? 0 : gi > 255 ? 255 : gi; bi = bi < 0 ? 0 : bi > 255 ? 255 : bi; color = Color.FromRgb((byte)ri, (byte)gi, (byte)bi); return(color, GraphicColorPrecision.Estimated); }
private void BrCalc_Lab() { BitmapEx bmp1, bmp2, bmp3; const int min = 5; const int max = 95; bmp1 = GetThumb(0, true); const uint ThumbWidth = 300; const uint ThumbHeight = 200; uint rowstride; int n = bmp1.ChannelCount; long index = 0; uint x, y; int x1, y1, maxCol = 8; double fact, d1, d2; List<double[]> PixelBrightness; bool[,] NonUseMask = new bool[ThumbWidth, ThumbHeight]; using (ColorConverter Converter = new ColorConverter()) { ColorLab[,] labimg1 = new ColorLab[ThumbWidth, ThumbHeight]; ColorLab[,] labimg2 = new ColorLab[ThumbWidth, ThumbHeight]; ColorLab[,] labimg3 = new ColorLab[ThumbWidth, ThumbHeight]; ColorRGB colrgb = new ColorRGB(new RGBColorspacesRGB()); ConversionRoutine rout = ColorConverter.FindRoutine(colrgb, labimg1[0, 0]); for (int f = 1; f < Frames.Count; f += 2) { if (MainWorker.CancellationPending) { return; } if (f + 2 >= Frames.Count) { f = Frames.Count - 2; } bmp1 = GetThumb(f - 1, false).Scale(ThumbWidth, ThumbHeight); bmp2 = GetThumb(f, false).Scale(ThumbWidth, ThumbHeight); bmp3 = GetThumb(f + 1, false).Scale(ThumbWidth, ThumbHeight); rowstride = bmp1.Stride; unsafe { bmp1.LockBits(); bmp2.LockBits(); bmp3.LockBits(); byte* pix1 = (byte*)bmp1.Scan0; byte* pix2 = (byte*)bmp2.Scan0; byte* pix3 = (byte*)bmp3.Scan0; //Non use Mask and Lab conversion for (y = 0; y < ThumbHeight; y++) { for (x = 0; x < ThumbWidth; x++) { index = y * rowstride + (x * n); colrgb.R = pix1[index]; colrgb.G = pix1[index + 1]; colrgb.B = pix1[index + 2]; Converter.Convert(colrgb, labimg1[x, y], rout); colrgb.R = pix2[index]; colrgb.G = pix2[index + 1]; colrgb.B = pix2[index + 2]; Converter.Convert(colrgb, labimg2[x, y], rout); colrgb.R = pix3[index]; colrgb.G = pix3[index + 1]; colrgb.B = pix3[index + 2]; Converter.Convert(colrgb, labimg3[x, y], rout); if (labimg1[x, y].L < min || labimg1[x, y].L > max || labimg2[x, y].L < min || labimg2[x, y].L > max || labimg3[x, y].L < min || labimg3[x, y].L > max || Math.Abs(labimg2[x, y].a - labimg1[x, y].a) > maxCol || Math.Abs(labimg3[x, y].a - labimg2[x, y].a) > maxCol || Math.Abs(labimg2[x, y].b - labimg1[x, y].b) > maxCol || Math.Abs(labimg3[x, y].b - labimg2[x, y].b) > maxCol) { NonUseMask[x, y] = true; } } } bmp1.UnlockBits(); bmp2.UnlockBits(); bmp3.UnlockBits(); } PixelBrightness = new List<double[]>(); //Brightness calculation for (y = 0; y < ThumbHeight; y++) { for (x = 0; x < ThumbWidth; x++) { if (!NonUseMask[x, y]) { fact = 0; if (y > 0 && x > 0 && y < ThumbHeight - 1 && x < ThumbWidth - 1) { d1 = 0; d2 = 0; for (y1 = -1; y1 <= 1; y1++) { for (x1 = -1; x1 <= 1; x1++) { d1 += Math.Abs(labimg1[x, y].L - labimg2[x, y].L); d2 += Math.Abs(labimg2[x, y].L - labimg3[x, y].L); } } fact = Math.Max(d1 / 9d, d2 / 9d); } if (fact > 0.2) PixelBrightness.Add(new double[] { fact * Math.Log(labimg1[x, y].L), fact * Math.Log(labimg2[x, y].L), fact * Math.Log(labimg3[x, y].L) }); } } } Frames[f - 1].OriginalBrightness = PixelBrightness.Average(p => p[0]); Frames[f].OriginalBrightness = PixelBrightness.Average(p => p[1]); Frames[f + 1].OriginalBrightness = PixelBrightness.Average(p => p[2]); Frames[f - 1].AlternativeBrightness = Frames[f - 1].OriginalBrightness; Frames[f].AlternativeBrightness = Frames[f].OriginalBrightness; Frames[f + 1].AlternativeBrightness = Frames[f + 1].OriginalBrightness; Frames[f - 1].NewBrightness = Frames[f - 1].OriginalBrightness; Frames[f].NewBrightness = Frames[f].OriginalBrightness; Frames[f + 1].NewBrightness = Frames[f + 1].OriginalBrightness; MainWorker.ReportProgress(0, new ProgressChangeEventArgs(f * 100 / (Frames.Count - 1), ProgressType.CalculateBrightness)); } } }
private void BrCalc_Lab() { BitmapEx bmp1, bmp2, bmp3; const int min = 5; const int max = 95; bmp1 = GetThumb(0, true); const uint ThumbWidth = 300; const uint ThumbHeight = 200; uint rowstride; int n = bmp1.ChannelCount; long index = 0; uint x, y; int x1, y1, maxCol = 8; double fact, d1, d2; List <double[]> PixelBrightness; bool[,] NonUseMask = new bool[ThumbWidth, ThumbHeight]; using (ColorConverter Converter = new ColorConverter()) { ColorLab[,] labimg1 = new ColorLab[ThumbWidth, ThumbHeight]; ColorLab[,] labimg2 = new ColorLab[ThumbWidth, ThumbHeight]; ColorLab[,] labimg3 = new ColorLab[ThumbWidth, ThumbHeight]; ColorRGB colrgb = new ColorRGB(new RGBColorspacesRGB()); ConversionRoutine rout = ColorConverter.FindRoutine(colrgb, labimg1[0, 0]); for (int f = 1; f < Frames.Count; f += 2) { if (MainWorker.CancellationPending) { return; } if (f + 2 >= Frames.Count) { f = Frames.Count - 2; } bmp1 = GetThumb(f - 1, false).Scale(ThumbWidth, ThumbHeight); bmp2 = GetThumb(f, false).Scale(ThumbWidth, ThumbHeight); bmp3 = GetThumb(f + 1, false).Scale(ThumbWidth, ThumbHeight); rowstride = bmp1.Stride; unsafe { bmp1.LockBits(); bmp2.LockBits(); bmp3.LockBits(); byte *pix1 = (byte *)bmp1.Scan0; byte *pix2 = (byte *)bmp2.Scan0; byte *pix3 = (byte *)bmp3.Scan0; //Non use Mask and Lab conversion for (y = 0; y < ThumbHeight; y++) { for (x = 0; x < ThumbWidth; x++) { index = y * rowstride + (x * n); colrgb.R = pix1[index]; colrgb.G = pix1[index + 1]; colrgb.B = pix1[index + 2]; Converter.Convert(colrgb, labimg1[x, y], rout); colrgb.R = pix2[index]; colrgb.G = pix2[index + 1]; colrgb.B = pix2[index + 2]; Converter.Convert(colrgb, labimg2[x, y], rout); colrgb.R = pix3[index]; colrgb.G = pix3[index + 1]; colrgb.B = pix3[index + 2]; Converter.Convert(colrgb, labimg3[x, y], rout); if (labimg1[x, y].L <min || labimg1[x, y].L> max || labimg2[x, y].L <min || labimg2[x, y].L> max || labimg3[x, y].L <min || labimg3[x, y].L> max || Math.Abs(labimg2[x, y].a - labimg1[x, y].a) > maxCol || Math.Abs(labimg3[x, y].a - labimg2[x, y].a) > maxCol || Math.Abs(labimg2[x, y].b - labimg1[x, y].b) > maxCol || Math.Abs(labimg3[x, y].b - labimg2[x, y].b) > maxCol) { NonUseMask[x, y] = true; } } } bmp1.UnlockBits(); bmp2.UnlockBits(); bmp3.UnlockBits(); } PixelBrightness = new List <double[]>(); //Brightness calculation for (y = 0; y < ThumbHeight; y++) { for (x = 0; x < ThumbWidth; x++) { if (!NonUseMask[x, y]) { fact = 0; if (y > 0 && x > 0 && y < ThumbHeight - 1 && x < ThumbWidth - 1) { d1 = 0; d2 = 0; for (y1 = -1; y1 <= 1; y1++) { for (x1 = -1; x1 <= 1; x1++) { d1 += Math.Abs(labimg1[x, y].L - labimg2[x, y].L); d2 += Math.Abs(labimg2[x, y].L - labimg3[x, y].L); } } fact = Math.Max(d1 / 9d, d2 / 9d); } if (fact > 0.2) { PixelBrightness.Add(new double[] { fact *Math.Log(labimg1[x, y].L), fact * Math.Log(labimg2[x, y].L), fact * Math.Log(labimg3[x, y].L) }); } } } } Frames[f - 1].OriginalBrightness = PixelBrightness.Average(p => p[0]); Frames[f].OriginalBrightness = PixelBrightness.Average(p => p[1]); Frames[f + 1].OriginalBrightness = PixelBrightness.Average(p => p[2]); Frames[f - 1].AlternativeBrightness = Frames[f - 1].OriginalBrightness; Frames[f].AlternativeBrightness = Frames[f].OriginalBrightness; Frames[f + 1].AlternativeBrightness = Frames[f + 1].OriginalBrightness; Frames[f - 1].NewBrightness = Frames[f - 1].OriginalBrightness; Frames[f].NewBrightness = Frames[f].OriginalBrightness; Frames[f + 1].NewBrightness = Frames[f + 1].OriginalBrightness; MainWorker.ReportProgress(0, new ProgressChangeEventArgs(f * 100 / (Frames.Count - 1), ProgressType.CalculateBrightness)); } } }
/// <summary> /// Creates a new instance of the <see cref="ColorDifference_CIE94"/> class /// </summary> /// <param name="Color1">First color to compare</param> /// <param name="Color2">Second color to compare</param> public ColorDifference_CIE94(ColorLab Color1, ColorLab Color2) : base(Color1, Color2) { }
/// <summary> /// Calculates the DE2000 delta-e value: http://en.wikipedia.org/wiki/Color_difference#CIEDE2000 /// Correct implementation provided courtesy of Jonathan Hofinger, jaytar42 /// </summary> public double Compare(ColorLab lab2, ColorLab lab1, bool quick = false) { //Set weighting factors to 1 double k_L = 1.0d; double k_C = 1.0d; double k_H = 1.0d; //Calculate Cprime1, Cprime2, Cabbar double c_star_1_ab = Math.Sqrt(lab1.A * lab1.A + lab1.B * lab1.B); double c_star_2_ab = Math.Sqrt(lab2.A * lab2.A + lab2.B * lab2.B); double c_star_average_ab = (c_star_1_ab + c_star_2_ab) / 2; double c_star_average_ab_pot7 = c_star_average_ab * c_star_average_ab * c_star_average_ab; c_star_average_ab_pot7 *= c_star_average_ab_pot7 * c_star_average_ab; double G = 0.5d * (1 - Math.Sqrt(c_star_average_ab_pot7 / (c_star_average_ab_pot7 + 6103515625))); //25^7 double a1_prime = (1 + G) * lab1.A; double a2_prime = (1 + G) * lab2.A; double C_prime_1 = Math.Sqrt(a1_prime * a1_prime + lab1.B * lab1.B); double C_prime_2 = Math.Sqrt(a2_prime * a2_prime + lab2.B * lab2.B); //Angles in Degree. double h_prime_1 = (MathUtils.RadToDeg(Math.Atan2(lab1.B, a1_prime)) + 360) % 360d; double h_prime_2 = (MathUtils.RadToDeg(Math.Atan2(lab2.B, a2_prime)) + 360) % 360d; double delta_L_prime = lab2.L - lab1.L; double delta_C_prime = C_prime_2 - C_prime_1; double h_bar = Math.Abs(h_prime_1 - h_prime_2); double delta_h_prime; if (C_prime_1 * C_prime_2 == 0) { delta_h_prime = 0; } else { if (h_bar <= 180d) { delta_h_prime = h_prime_2 - h_prime_1; } else if (h_bar > 180d && h_prime_2 <= h_prime_1) { delta_h_prime = h_prime_2 - h_prime_1 + 360.0; } else { delta_h_prime = h_prime_2 - h_prime_1 - 360.0; } } double delta_H_prime = 2 * Math.Sqrt(C_prime_1 * C_prime_2) * Math.Sin(MathUtils.DegToRad(delta_h_prime / 2)); // Calculate CIEDE2000 double L_prime_average = (lab1.L + lab2.L) / 2d; double C_prime_average = (C_prime_1 + C_prime_2) / 2d; //Calculate h_prime_average double h_prime_average; if (C_prime_1 * C_prime_2 == 0) { h_prime_average = 0; } else { if (h_bar <= 180d) { h_prime_average = (h_prime_1 + h_prime_2) / 2; } else if (h_bar > 180d && (h_prime_1 + h_prime_2) < 360d) { h_prime_average = (h_prime_1 + h_prime_2 + 360d) / 2; } else { h_prime_average = (h_prime_1 + h_prime_2 - 360d) / 2; } } double L_prime_average_minus_50_square = (L_prime_average - 50); L_prime_average_minus_50_square *= L_prime_average_minus_50_square; double S_L = 1 + ((.015d * L_prime_average_minus_50_square) / Math.Sqrt(20 + L_prime_average_minus_50_square)); double S_C = 1 + .045d * C_prime_average; double T = 1 - .17 * Math.Cos(MathUtils.DegToRad(h_prime_average - 30)) + .24 * Math.Cos(MathUtils.DegToRad(h_prime_average * 2)) + .32 * Math.Cos(MathUtils.DegToRad(h_prime_average * 3 + 6)) - .2 * Math.Cos(MathUtils.DegToRad(h_prime_average * 4 - 63)); double S_H = 1 + .015 * T * C_prime_average; double h_prime_average_minus_275_div_25_square = (h_prime_average - 275) / (25); h_prime_average_minus_275_div_25_square *= h_prime_average_minus_275_div_25_square; double delta_theta = 30 * Math.Exp(-h_prime_average_minus_275_div_25_square); double C_prime_average_pot_7 = C_prime_average * C_prime_average * C_prime_average; C_prime_average_pot_7 *= C_prime_average_pot_7 * C_prime_average; double R_C = 2 * Math.Sqrt(C_prime_average_pot_7 / (C_prime_average_pot_7 + 6103515625)); double R_T = -Math.Sin(MathUtils.DegToRad(2 * delta_theta)) * R_C; double delta_L_prime_div_k_L_S_L = delta_L_prime / (S_L * k_L); double delta_C_prime_div_k_C_S_C = delta_C_prime / (S_C * k_C); double delta_H_prime_div_k_H_S_H = delta_H_prime / (S_H * k_H); double CIEDE2000 = Math.Sqrt( delta_L_prime_div_k_L_S_L * delta_L_prime_div_k_L_S_L + delta_C_prime_div_k_C_S_C * delta_C_prime_div_k_C_S_C + delta_H_prime_div_k_H_S_H * delta_H_prime_div_k_H_S_H + R_T * delta_C_prime_div_k_C_S_C * delta_H_prime_div_k_H_S_H ); return(CIEDE2000); }