public static ColorDistribution Add(ColorDistribution dist1, ColorDistribution dist2) { Contract.Requires(dist1 != null); Contract.Requires(dist2 != null); var result = new ColorDistribution(dist1.Hues, dist1.Saturations, dist1.Values); result.Add(dist1); result.Add(dist2); return result; }
public static double GetCorrelationCoefficient(ColorDistribution dist1, ColorDistribution dist2) { Contract.Requires(dist1 != null); Contract.Requires(dist2 != null); Contract.Requires(dist1.Hues == dist2.Hues); Contract.Requires(dist1.Saturations == dist2.Saturations); Contract.Requires(dist1.Values == dist2.Values); var a = dist1.GetMostCommonColor(); var b = dist2.GetMostCommonColor(); // normalize deltas to 0..100 var deltaH = (a.H - b.H) * 100.0 / 360.0; var deltaS = (a.S - b.S) * 100.0; var deltaV = (a.V - b.V) * 100.0; var distance = Math.Sqrt(deltaH * deltaH + deltaS * deltaS + deltaV * deltaV); const double maxDistance = 173.2051; //Math.Sqrt(100*100 + 100*100 + 100*100); return distance / maxDistance; }
public void TestCorrelation() { var dist1 = new ColorDistribution(36, 10, 10); var dist2 = new ColorDistribution(36, 10, 10); Assert.That(ColorDistribution.GetCorrelationCoefficient(dist1, dist2), Is.EqualTo(0.0)); dist1 = CreateSampleDistribution(); dist2 = CreateSampleDistribution(); Assert.That(ColorDistribution.GetCorrelationCoefficient(dist1, dist2), Is.EqualTo(0.0)); dist1 = new ColorDistribution(36, 10, 10) .AddPixel(ColorHsv.FromHsv(0.0, 0.0, 0.0)); dist2 = new ColorDistribution(36, 10, 10) .AddPixel(ColorHsv.FromHsv(359.0, 1.0, 1.0)); Assert.That(ColorDistribution.GetCorrelationCoefficient(dist1, dist2), Is.GreaterThan(0.9).And.LessThanOrEqualTo(1.0)); }
public void TestDominantColor() { var distribution = CreateSampleDistribution(); Assert.That(distribution.GetDominantColor(), Is.EqualTo( ColorHsv.FromHsv(120.0, 0.49, 0.49))); distribution = new ColorDistribution(360, 100, 100) .AddPixel(ColorHsv.FromHsv(100.0, 0.0, 0.0)) .AddPixel(ColorHsv.FromHsv(100.0, 0.0, 0.0)) .AddPixel(ColorHsv.FromHsv(100.0, 0.0, 0.1)) .AddPixel(ColorHsv.FromHsv(100.0, 0.0, 0.1)) .AddPixel(ColorHsv.FromHsv(100.0, 0.1, 0.0)) .AddPixel(ColorHsv.FromHsv(100.0, 0.1, 0.0)) .AddPixel(ColorHsv.FromHsv(200.0, 0.5, 0.5)); Assert.That(distribution.GetDominantColor(), Is.EqualTo( ColorHsv.FromHsv(200.0, 0.49, 0.49))); }
public void TestGranularities() { var distribution = new ColorDistribution(180, 10, 5); Assert.That(distribution.Hues, Is.EqualTo(180)); Assert.That(distribution.Saturations, Is.EqualTo(10)); Assert.That(distribution.Values, Is.EqualTo(5)); Assert.That(distribution.HueGranularity, Is.EqualTo(0.5)); Assert.That(distribution.SaturationGranularity, Is.EqualTo(10.0)); Assert.That(distribution.ValueGranularity, Is.EqualTo(5.0)); }
/// <summary> /// Analyzes the image and calculates the color distribution. /// </summary> /// <param name="hueSteps">The number of steps to use for the hue distribution. The granularity /// of the hue distribution is <paramref name="hueSteps"/> divided by 360 degrees. /// </param> /// <param name="saturationSteps">The number of steps to use for the saturation distribution.</param> /// <param name="valueSteps">The number of steps to use for the value distribution.</param> /// <returns>An instance of <see cref="ColorDistribution"/>. The method /// <see cref="ColorDistribution.GetHueDistribution"/> returns <paramref name="hueSteps"/> elements.</returns> public ColorDistribution GetColorDistribution(int hueSteps, int saturationSteps, int valueSteps) { var distribution = new ColorDistribution(hueSteps, saturationSteps, valueSteps); foreach (var hsv in hsvPixels) distribution.AddPixel(hsv); return distribution; }
/// <summary> /// Analyzes the image and calculates the color distribution. /// </summary> /// <param name="hueSteps">The number of steps to use for the hue distribution. The granularity /// of the hue distribution is <paramref name="hueSteps"/> divided by 360 degrees. /// </param> /// <param name="saturationSteps">The number of steps to use for the saturation distribution.</param> /// <param name="valueSteps">The number of steps to use for the value distribution.</param> /// <param name="rect">The image region to process.</param> /// <returns>An instance of <see cref="ColorDistribution"/>. The method /// <see cref="ColorDistribution.GetHueDistribution"/> returns <paramref name="hueSteps"/> elements.</returns> public ColorDistribution GetColorDistribution(int hueSteps, int saturationSteps, int valueSteps, Rectangle rect) { Contract.Requires(rect.Left >= 0 && rect.Left <= Bitmap.Width && rect.Right >= 0 && rect.Right <= Bitmap.Width && rect.Top >= 0 && rect.Top <= Bitmap.Height && rect.Bottom >= 0 && rect.Bottom <= Bitmap.Height); var distribution = new ColorDistribution(hueSteps, saturationSteps, valueSteps); for (var y = 0; y < rect.Height; y++) { var offset = Bitmap.Width * y + rect.Left; for (var x = 0; x < rect.Width; x++) distribution.AddPixel(this.hsvPixels[offset + x]); } return distribution; }
internal void Add(ColorDistribution other) { Contract.Requires(other != null); Contract.Requires(other.Hues == Hues); Contract.Requires(other.Saturations == Saturations); Contract.Requires(other.Values == Values); var countH = Hues; var countS = Saturations; var countV = Values; Parallel.For(0, countH, indexH => { for (var indexS = 0; indexS < countS; indexS++) { for (var indexV = 0; indexV < countV; indexV++) this.cube[indexH, indexS, indexV] += other.cube[indexH, indexS, indexV]; } }); }