public static void then_should_add_each_property_value_together() { // Arrange var colorMoment1 = new ColorMoment { Alpha = 1, Blue = 2, Green = 3, Moment = 4, Red = 5, Weight = 6}; var colorMoment2 = new ColorMoment { Alpha = 6, Blue = 5, Green = 4, Moment = 3, Red = 2, Weight = 1}; // Act var addedColor = colorMoment1 + colorMoment2; // Assert Assert.That(addedColor.Alpha, Is.EqualTo(7)); Assert.That(addedColor.Blue, Is.EqualTo(7)); Assert.That(addedColor.Green, Is.EqualTo(7)); Assert.That(addedColor.Moment, Is.EqualTo(7)); Assert.That(addedColor.Red, Is.EqualTo(7)); Assert.That(addedColor.Weight, Is.EqualTo(7)); }
public static void then_should_add_each_property_value_together() { // Arrange var colorMoment = new ColorMoment { Alpha = 1, Blue = 2, Green = 3, Moment = 4, Red = 5, Weight = 6 }; var color32 = new Color32(6, 5, 4, 3); // Act colorMoment.Add(color32); // Assert Assert.That(colorMoment.Alpha, Is.EqualTo(7)); Assert.That(colorMoment.Red, Is.EqualTo(10)); Assert.That(colorMoment.Green, Is.EqualTo(7)); Assert.That(colorMoment.Blue, Is.EqualTo(5)); Assert.That(colorMoment.Moment, Is.EqualTo(90f)); Assert.That(colorMoment.Weight, Is.EqualTo(7)); }
public static void then_should_subtract_each_property() { // Arrange var colorMoment1 = new ColorMoment { Alpha = 6, Blue = 6, Green = 6, Moment = 6, Red = 6, Weight = 6 }; var colorMoment2 = new ColorMoment { Alpha = 6, Blue = 5, Green = 4, Moment = 3, Red = 2, Weight = 1 }; // Act var addedColor = colorMoment1 - colorMoment2; // Assert Assert.That(addedColor.Alpha, Is.EqualTo(0)); Assert.That(addedColor.Blue, Is.EqualTo(1)); Assert.That(addedColor.Green, Is.EqualTo(2)); Assert.That(addedColor.Moment, Is.EqualTo(3)); Assert.That(addedColor.Red, Is.EqualTo(4)); Assert.That(addedColor.Weight, Is.EqualTo(5)); }
private static Color32[] BuildLookups(Box[] cubes, ColorMoment[,,,] moments) { var lookups = new Color32[cubes.Length]; for (int cubeIndex = 0; cubeIndex < cubes.Length; cubeIndex++) { ColorMoment volume = Volume(moments, cubes[cubeIndex]); if (volume.Weight <= 0) { continue; } lookups[cubeIndex] = new Color32 { A = (byte)(volume.Alpha / volume.Weight), R = (byte)(volume.Red / volume.Weight), G = (byte)(volume.Green / volume.Weight), B = (byte)(volume.Blue / volume.Weight) }; } return(lookups); }
private static CubeCut Maximize(ColorMoment[,,,] moments, Box cube, int direction, byte first, byte last, ColorMoment whole) { ColorMoment bottom = Bottom(cube, direction, moments); float result = 0.0f; byte? cutPoint = null; for (byte position = first; position < last; ++position) { ColorMoment half = bottom + Top(cube, direction, position, moments); if (half.Weight == 0) { continue; } long temp = half.WeightedDistance(); half = whole - half; if (half.Weight != 0) { temp += half.WeightedDistance(); if (temp > result) { result = temp; cutPoint = position; } } } return(new CubeCut(cutPoint, result)); }
private static Color32[] BuildLookups(Box[] cubes, ColorMoment[, , ,] moments) { Color32[] lookups = new Color32[cubes.Length]; for (int cubeIndex = 0; cubeIndex < cubes.Length; cubeIndex++) { ColorMoment volume = Volume(moments, cubes[cubeIndex]); if (volume.Weight <= 0) { continue; } Color32 lookup = new Color32 { A = (byte)(volume.Alpha / volume.Weight), R = (byte)(volume.Red / volume.Weight), G = (byte)(volume.Green / volume.Weight), B = (byte)(volume.Blue / volume.Weight) }; lookups[cubeIndex] = lookup; } return lookups; }
private static Box[] SplitData(ref int colorCount, ColorMoment[, , ,] moments) { --colorCount; int next = 0; float[] volumeVariance = new float[colorCount]; Box[] cubes = new Box[colorCount]; cubes[0].AlphaMaximum = MaxSideIndex; cubes[0].RedMaximum = MaxSideIndex; cubes[0].GreenMaximum = MaxSideIndex; cubes[0].BlueMaximum = MaxSideIndex; for (int cubeIndex = 1; cubeIndex < colorCount; ++cubeIndex) { if (Cut(moments, ref cubes[next], ref cubes[cubeIndex])) { volumeVariance[next] = cubes[next].Size > 1 ? CalculateVariance(moments, cubes[next]) : 0.0f; volumeVariance[cubeIndex] = cubes[cubeIndex].Size > 1 ? CalculateVariance(moments, cubes[cubeIndex]) : 0.0f; } else { volumeVariance[next] = 0.0f; cubeIndex--; } next = 0; float temp = volumeVariance[0]; for (int index = 1; index <= cubeIndex; ++index) { if (volumeVariance[index] <= temp) { continue; } temp = volumeVariance[index]; next = index; } if (temp > 0.0) { continue; } colorCount = cubeIndex + 1; break; } return cubes.Take(colorCount).ToArray(); }
private static ColorMoment Volume(ColorMoment[, , ,] moments, Box cube) { return (moments[cube.AlphaMaximum, cube.RedMaximum, cube.GreenMaximum, cube.BlueMaximum] - moments[cube.AlphaMaximum, cube.RedMaximum, cube.GreenMinimum, cube.BlueMaximum] - moments[cube.AlphaMaximum, cube.RedMinimum, cube.GreenMaximum, cube.BlueMaximum] + moments[cube.AlphaMaximum, cube.RedMinimum, cube.GreenMinimum, cube.BlueMaximum] - moments[cube.AlphaMinimum, cube.RedMaximum, cube.GreenMaximum, cube.BlueMaximum] + moments[cube.AlphaMinimum, cube.RedMaximum, cube.GreenMinimum, cube.BlueMaximum] + moments[cube.AlphaMinimum, cube.RedMinimum, cube.GreenMaximum, cube.BlueMaximum] - moments[cube.AlphaMinimum, cube.RedMinimum, cube.GreenMinimum, cube.BlueMaximum]) - (moments[cube.AlphaMaximum, cube.RedMaximum, cube.GreenMaximum, cube.BlueMinimum] - moments[cube.AlphaMinimum, cube.RedMaximum, cube.GreenMaximum, cube.BlueMinimum] - moments[cube.AlphaMaximum, cube.RedMaximum, cube.GreenMinimum, cube.BlueMinimum] + moments[cube.AlphaMinimum, cube.RedMaximum, cube.GreenMinimum, cube.BlueMinimum] - moments[cube.AlphaMaximum, cube.RedMinimum, cube.GreenMaximum, cube.BlueMinimum] + moments[cube.AlphaMinimum, cube.RedMinimum, cube.GreenMaximum, cube.BlueMinimum] + moments[cube.AlphaMaximum, cube.RedMinimum, cube.GreenMinimum, cube.BlueMinimum] - moments[cube.AlphaMinimum, cube.RedMinimum, cube.GreenMinimum, cube.BlueMinimum]); }
private static float CalculateVariance(ColorMoment[, , ,] moments, Box cube) { ColorMoment volume = Volume(moments, cube); return volume.Variance(); }
public static void then_should_return_amplitude_divided_by_weight_rounded_down() { // Arrange var colorMoment = new ColorMoment { Alpha = 1, Blue = 2, Green = 3, Moment = 4, Red = 5, Weight = 6 }; // Act var amplitude = colorMoment.WeightedDistance(); // Assert Assert.That(amplitude, Is.EqualTo(6)); }
private static ColorMoment Bottom(Box cube, int direction, ColorMoment[, , ,] moment) { switch (direction) { case Alpha: return (-moment[cube.AlphaMinimum, cube.RedMaximum, cube.GreenMaximum, cube.BlueMaximum] + moment[cube.AlphaMinimum, cube.RedMaximum, cube.GreenMinimum, cube.BlueMaximum] + moment[cube.AlphaMinimum, cube.RedMinimum, cube.GreenMaximum, cube.BlueMaximum] - moment[cube.AlphaMinimum, cube.RedMinimum, cube.GreenMinimum, cube.BlueMaximum]) - (-moment[cube.AlphaMinimum, cube.RedMaximum, cube.GreenMaximum, cube.BlueMinimum] + moment[cube.AlphaMinimum, cube.RedMaximum, cube.GreenMinimum, cube.BlueMinimum] + moment[cube.AlphaMinimum, cube.RedMinimum, cube.GreenMaximum, cube.BlueMinimum] - moment[cube.AlphaMinimum, cube.RedMinimum, cube.GreenMinimum, cube.BlueMinimum]); case Red: return (-moment[cube.AlphaMaximum, cube.RedMinimum, cube.GreenMaximum, cube.BlueMaximum] + moment[cube.AlphaMaximum, cube.RedMinimum, cube.GreenMinimum, cube.BlueMaximum] + moment[cube.AlphaMinimum, cube.RedMinimum, cube.GreenMaximum, cube.BlueMaximum] - moment[cube.AlphaMinimum, cube.RedMinimum, cube.GreenMinimum, cube.BlueMaximum]) - (-moment[cube.AlphaMaximum, cube.RedMinimum, cube.GreenMaximum, cube.BlueMinimum] + moment[cube.AlphaMaximum, cube.RedMinimum, cube.GreenMinimum, cube.BlueMinimum] + moment[cube.AlphaMinimum, cube.RedMinimum, cube.GreenMaximum, cube.BlueMinimum] - moment[cube.AlphaMinimum, cube.RedMinimum, cube.GreenMinimum, cube.BlueMinimum]); case Green: return (-moment[cube.AlphaMaximum, cube.RedMaximum, cube.GreenMinimum, cube.BlueMaximum] + moment[cube.AlphaMaximum, cube.RedMinimum, cube.GreenMinimum, cube.BlueMaximum] + moment[cube.AlphaMinimum, cube.RedMaximum, cube.GreenMinimum, cube.BlueMaximum] - moment[cube.AlphaMinimum, cube.RedMinimum, cube.GreenMinimum, cube.BlueMaximum]) - (-moment[cube.AlphaMaximum, cube.RedMaximum, cube.GreenMinimum, cube.BlueMinimum] + moment[cube.AlphaMaximum, cube.RedMinimum, cube.GreenMinimum, cube.BlueMinimum] + moment[cube.AlphaMinimum, cube.RedMaximum, cube.GreenMinimum, cube.BlueMinimum] - moment[cube.AlphaMinimum, cube.RedMinimum, cube.GreenMinimum, cube.BlueMinimum]); case Blue: return (-moment[cube.AlphaMaximum, cube.RedMaximum, cube.GreenMaximum, cube.BlueMinimum] + moment[cube.AlphaMaximum, cube.RedMaximum, cube.GreenMinimum, cube.BlueMinimum] + moment[cube.AlphaMaximum, cube.RedMinimum, cube.GreenMaximum, cube.BlueMinimum] - moment[cube.AlphaMaximum, cube.RedMinimum, cube.GreenMinimum, cube.BlueMinimum]) - (-moment[cube.AlphaMinimum, cube.RedMaximum, cube.GreenMaximum, cube.BlueMinimum] + moment[cube.AlphaMinimum, cube.RedMaximum, cube.GreenMinimum, cube.BlueMinimum] + moment[cube.AlphaMinimum, cube.RedMinimum, cube.GreenMaximum, cube.BlueMinimum] - moment[cube.AlphaMinimum, cube.RedMinimum, cube.GreenMinimum, cube.BlueMinimum]); default: return new ColorMoment(); } }
private static void CalculateMoments(ColorMoment[, , ,] moments) { ColorMoment[,] areaSquared = new ColorMoment[SideSize, SideSize]; ColorMoment[] area = new ColorMoment[SideSize]; for (int alphaIndex = 1; alphaIndex < SideSize; alphaIndex++) { for (int redIndex = 1; redIndex < SideSize; redIndex++) { Array.Clear(area, 0, area.Length); for (int greenIndex = 1; greenIndex < SideSize; greenIndex++) { ColorMoment line = new ColorMoment(); for (int blueIndex = 1; blueIndex < SideSize; blueIndex++) { line.AddFast(ref moments[alphaIndex, redIndex, greenIndex, blueIndex]); area[blueIndex].AddFast(ref line); areaSquared[greenIndex, blueIndex].AddFast(ref area[blueIndex]); ColorMoment moment = moments[alphaIndex - 1, redIndex, greenIndex, blueIndex]; moment.AddFast(ref areaSquared[greenIndex, blueIndex]); moments[alphaIndex, redIndex, greenIndex, blueIndex] = moment; } } } } }
public static void then_should_add_each_property_value_together() { // Arrange var colorMoment = new ColorMoment { Alpha = 1, Blue = 2, Green = 3, Moment = 4, Red = 5, Weight = 6 }; // Act colorMoment.AddFast(ref colorMoment); // Assert Assert.That(colorMoment.Alpha, Is.EqualTo(2)); Assert.That(colorMoment.Red, Is.EqualTo(10)); Assert.That(colorMoment.Green, Is.EqualTo(6)); Assert.That(colorMoment.Blue, Is.EqualTo(4)); Assert.That(colorMoment.Moment, Is.EqualTo(8.0f)); Assert.That(colorMoment.Weight, Is.EqualTo(12)); }
public static void then_should_return_moment_minus_amplitude_divided_by_weight() { // Arrange var colorMoment = new ColorMoment { Alpha = 1, Blue = 2, Green = 3, Moment = 24, Red = 5, Weight = 6 }; // Act var amplitude = colorMoment.Variance(); // Assert Assert.That(amplitude, Is.EqualTo(17.5f)); }
private static bool Cut(ColorMoment[,,,] moments, ref Box first, ref Box second) { int direction; ColorMoment whole = Volume(moments, first); CubeCut maxAlpha = Maximize(moments, first, Alpha, (byte)(first.AlphaMinimum + 1), first.AlphaMaximum, whole); CubeCut maxRed = Maximize(moments, first, Red, (byte)(first.RedMinimum + 1), first.RedMaximum, whole); CubeCut maxGreen = Maximize(moments, first, Green, (byte)(first.GreenMinimum + 1), first.GreenMaximum, whole); CubeCut maxBlue = Maximize(moments, first, Blue, (byte)(first.BlueMinimum + 1), first.BlueMaximum, whole); if ((maxAlpha.Value >= maxRed.Value) && (maxAlpha.Value >= maxGreen.Value) && (maxAlpha.Value >= maxBlue.Value)) { direction = Alpha; if (maxAlpha.Position == null) { return(false); } } else if ((maxRed.Value >= maxAlpha.Value) && (maxRed.Value >= maxGreen.Value) && (maxRed.Value >= maxBlue.Value)) { direction = Red; } else { if ((maxGreen.Value >= maxAlpha.Value) && (maxGreen.Value >= maxRed.Value) && (maxGreen.Value >= maxBlue.Value)) { direction = Green; } else { direction = Blue; } } second.AlphaMaximum = first.AlphaMaximum; second.RedMaximum = first.RedMaximum; second.GreenMaximum = first.GreenMaximum; second.BlueMaximum = first.BlueMaximum; switch (direction) { case Alpha: if (maxAlpha.Position == null) { return(false); } second.AlphaMinimum = first.AlphaMaximum = (byte)maxAlpha.Position; second.RedMinimum = first.RedMinimum; second.GreenMinimum = first.GreenMinimum; second.BlueMinimum = first.BlueMinimum; break; case Red: if (maxRed.Position == null) { return(false); } second.RedMinimum = first.RedMaximum = (byte)maxRed.Position; second.AlphaMinimum = first.AlphaMinimum; second.GreenMinimum = first.GreenMinimum; second.BlueMinimum = first.BlueMinimum; break; case Green: if (maxGreen.Position == null) { return(false); } second.GreenMinimum = first.GreenMaximum = (byte)maxGreen.Position; second.AlphaMinimum = first.AlphaMinimum; second.RedMinimum = first.RedMinimum; second.BlueMinimum = first.BlueMinimum; break; case Blue: if (maxBlue.Position == null) { return(false); } second.BlueMinimum = first.BlueMaximum = (byte)maxBlue.Position; second.AlphaMinimum = first.AlphaMinimum; second.RedMinimum = first.RedMinimum; second.GreenMinimum = first.GreenMinimum; break; } first.Size = (first.AlphaMaximum - first.AlphaMinimum) * (first.RedMaximum - first.RedMinimum) * (first.GreenMaximum - first.GreenMinimum) * (first.BlueMaximum - first.BlueMinimum); second.Size = (second.AlphaMaximum - second.AlphaMinimum) * (second.RedMaximum - second.RedMinimum) * (second.GreenMaximum - second.GreenMinimum) * (second.BlueMaximum - second.BlueMinimum); return(true); }
private static CubeCut Maximize(ColorMoment[, , ,] moments, Box cube, int direction, byte first, byte last, ColorMoment whole) { ColorMoment bottom = Bottom(cube, direction, moments); float result = 0.0f; byte? cutPoint = null; for (byte position = first; position < last; ++position) { ColorMoment half = bottom + Top(cube, direction, position, moments); if (half.Weight == 0) { continue; } long temp = half.WeightedDistance(); half = whole - half; if (half.Weight != 0) { temp += half.WeightedDistance(); if (temp > result) { result = temp; cutPoint = position; } } } return new CubeCut(cutPoint, result); }
private static float CalculateVariance(ColorMoment[,,,] moments, Box cube) { ColorMoment volume = Volume(moments, cube); return(volume.Variance()); }
private static bool Cut(ColorMoment[, , ,] moments, ref Box first, ref Box second) { int direction; ColorMoment whole = Volume(moments, first); CubeCut maxAlpha = Maximize(moments, first, Alpha, (byte)(first.AlphaMinimum + 1), first.AlphaMaximum, whole); CubeCut maxRed = Maximize(moments, first, Red, (byte)(first.RedMinimum + 1), first.RedMaximum, whole); CubeCut maxGreen = Maximize(moments, first, Green, (byte)(first.GreenMinimum + 1), first.GreenMaximum, whole); CubeCut maxBlue = Maximize(moments, first, Blue, (byte)(first.BlueMinimum + 1), first.BlueMaximum, whole); if ((maxAlpha.Value >= maxRed.Value) && (maxAlpha.Value >= maxGreen.Value) && (maxAlpha.Value >= maxBlue.Value)) { direction = Alpha; if (maxAlpha.Position == null) { return false; } } else if ((maxRed.Value >= maxAlpha.Value) && (maxRed.Value >= maxGreen.Value) && (maxRed.Value >= maxBlue.Value)) { direction = Red; } else { if ((maxGreen.Value >= maxAlpha.Value) && (maxGreen.Value >= maxRed.Value) && (maxGreen.Value >= maxBlue.Value)) { direction = Green; } else { direction = Blue; } } second.AlphaMaximum = first.AlphaMaximum; second.RedMaximum = first.RedMaximum; second.GreenMaximum = first.GreenMaximum; second.BlueMaximum = first.BlueMaximum; switch (direction) { case Alpha: if (maxAlpha.Position == null) { return false; } second.AlphaMinimum = first.AlphaMaximum = (byte)maxAlpha.Position; second.RedMinimum = first.RedMinimum; second.GreenMinimum = first.GreenMinimum; second.BlueMinimum = first.BlueMinimum; break; case Red: if (maxRed.Position == null) { return false; } second.RedMinimum = first.RedMaximum = (byte)maxRed.Position; second.AlphaMinimum = first.AlphaMinimum; second.GreenMinimum = first.GreenMinimum; second.BlueMinimum = first.BlueMinimum; break; case Green: if (maxGreen.Position == null) { return false; } second.GreenMinimum = first.GreenMaximum = (byte)maxGreen.Position; second.AlphaMinimum = first.AlphaMinimum; second.RedMinimum = first.RedMinimum; second.BlueMinimum = first.BlueMinimum; break; case Blue: if (maxBlue.Position == null) { return false; } second.BlueMinimum = first.BlueMaximum = (byte)maxBlue.Position; second.AlphaMinimum = first.AlphaMinimum; second.RedMinimum = first.RedMinimum; second.GreenMinimum = first.GreenMinimum; break; } first.Size = (first.AlphaMaximum - first.AlphaMinimum) * (first.RedMaximum - first.RedMinimum) * (first.GreenMaximum - first.GreenMinimum) * (first.BlueMaximum - first.BlueMinimum); second.Size = (second.AlphaMaximum - second.AlphaMinimum) * (second.RedMaximum - second.RedMinimum) * (second.GreenMaximum - second.GreenMinimum) * (second.BlueMaximum - second.BlueMinimum); return true; }
/// <summary> /// Adds a color moment to the current instance more quickly. /// </summary> /// <param name="moment"> /// The <see cref="ColorMoment"/> to add. /// </param> public void AddFast(ref ColorMoment moment) { this.Alpha += moment.Alpha; this.Red += moment.Red; this.Green += moment.Green; this.Blue += moment.Blue; this.Weight += moment.Weight; this.Moment += moment.Moment; }
public static void then_should_multiply_each_property_value_together() { // Arrange var colorMoment = new ColorMoment { Alpha = 1, Blue = 2, Green = 3, Moment = 4, Red = 5, Weight = 6 }; // Act var amplitude = colorMoment.Amplitude(); // Assert Assert.That(amplitude, Is.EqualTo(39)); }