mirror of https://github.com/SixLabors/ImageSharp
Browse Source
Former-commit-id: b234976a3f56b6a1c759bfc82d9a39bf86d98769 Former-commit-id: 66529c17cd81a103e0a7627244b208db3a6f9d2faf/merge-core
8 changed files with 231 additions and 73 deletions
@ -0,0 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:91c2a86b4f41313c9db541649ae0a97661a45ade40bb70b1ec784ab60b065e55 |
|||
size 171 |
|||
@ -1,86 +1,186 @@ |
|||
|
|||
// --------------------------------------------------------------------------------------------------------------------
|
|||
// <copyright file="ColorMoment.cs" company="James South">
|
|||
// Copyright (c) James South.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
// <summary>
|
|||
// The color moment for holding pixel information.
|
|||
// Adapted from <see href="https://github.com/drewnoakes" />
|
|||
// </summary>
|
|||
// --------------------------------------------------------------------------------------------------------------------
|
|||
|
|||
namespace ImageProcessor.Imaging.Quantizers.WuQuantizer |
|||
{ |
|||
/// <summary>
|
|||
/// The color moment for holding pixel information.
|
|||
/// Adapted from <see href="https://github.com/drewnoakes" />
|
|||
/// </summary>
|
|||
internal struct ColorMoment |
|||
{ |
|||
/// <summary>
|
|||
/// The alpha.
|
|||
/// </summary>
|
|||
public long Alpha; |
|||
public long Red; |
|||
public long Green; |
|||
|
|||
/// <summary>
|
|||
/// The blue.
|
|||
/// </summary>
|
|||
public long Blue; |
|||
public int Weight; |
|||
|
|||
/// <summary>
|
|||
/// The green.
|
|||
/// </summary>
|
|||
public long Green; |
|||
|
|||
/// <summary>
|
|||
/// The moment.
|
|||
/// </summary>
|
|||
public float Moment; |
|||
|
|||
public static ColorMoment operator +(ColorMoment c1, ColorMoment c2) |
|||
{ |
|||
c1.Alpha += c2.Alpha; |
|||
c1.Red += c2.Red; |
|||
c1.Green += c2.Green; |
|||
c1.Blue += c2.Blue; |
|||
c1.Weight += c2.Weight; |
|||
c1.Moment += c2.Moment; |
|||
return c1; |
|||
} |
|||
/// <summary>
|
|||
/// The red.
|
|||
/// </summary>
|
|||
public long Red; |
|||
|
|||
public static ColorMoment operator -(ColorMoment c1, ColorMoment c2) |
|||
/// <summary>
|
|||
/// The weight.
|
|||
/// </summary>
|
|||
public int Weight; |
|||
|
|||
/// <summary>
|
|||
/// Adds one <see cref="ColorMoment"/> to another.
|
|||
/// </summary>
|
|||
/// <param name="firstAddend">
|
|||
/// The first <see cref="ColorMoment"/>.
|
|||
/// </param>
|
|||
/// <param name="secondAddend">
|
|||
/// The second <see cref="ColorMoment"/>.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// The <see cref="ColorMoment"/> representing the sum of the addition.
|
|||
/// </returns>
|
|||
public static ColorMoment operator +(ColorMoment firstAddend, ColorMoment secondAddend) |
|||
{ |
|||
c1.Alpha -= c2.Alpha; |
|||
c1.Red -= c2.Red; |
|||
c1.Green -= c2.Green; |
|||
c1.Blue -= c2.Blue; |
|||
c1.Weight -= c2.Weight; |
|||
c1.Moment -= c2.Moment; |
|||
return c1; |
|||
firstAddend.Alpha += secondAddend.Alpha; |
|||
firstAddend.Red += secondAddend.Red; |
|||
firstAddend.Green += secondAddend.Green; |
|||
firstAddend.Blue += secondAddend.Blue; |
|||
firstAddend.Weight += secondAddend.Weight; |
|||
firstAddend.Moment += secondAddend.Moment; |
|||
return firstAddend; |
|||
} |
|||
|
|||
public static ColorMoment operator -(ColorMoment c1) |
|||
/// <summary>
|
|||
/// Subtracts one <see cref="ColorMoment "/> from another.
|
|||
/// </summary>
|
|||
/// <param name="minuend">
|
|||
/// The <see cref="ColorMoment"/> from which the other <see cref="ColorMoment"/> will be subtracted
|
|||
/// </param>
|
|||
/// <param name="subtrahend">
|
|||
/// The <see cref="ColorMoment"/> that is to be subtracted.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// The <see cref="ColorMoment"/> representing the difference of the subtraction.
|
|||
/// </returns>
|
|||
public static ColorMoment operator -(ColorMoment minuend, ColorMoment subtrahend) |
|||
{ |
|||
c1.Alpha = -c1.Alpha; |
|||
c1.Red = -c1.Red; |
|||
c1.Green = -c1.Green; |
|||
c1.Blue = -c1.Blue; |
|||
c1.Weight = -c1.Weight; |
|||
c1.Moment = -c1.Moment; |
|||
return c1; |
|||
minuend.Alpha -= subtrahend.Alpha; |
|||
minuend.Red -= subtrahend.Red; |
|||
minuend.Green -= subtrahend.Green; |
|||
minuend.Blue -= subtrahend.Blue; |
|||
minuend.Weight -= subtrahend.Weight; |
|||
minuend.Moment -= subtrahend.Moment; |
|||
return minuend; |
|||
} |
|||
|
|||
public void Add(Pixel p) |
|||
/// <summary>
|
|||
/// Negates the given <see cref="ColorMoment"/> .
|
|||
/// </summary>
|
|||
/// <param name="moment">
|
|||
/// The <see cref="ColorMoment"/> to negate.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// The negated result
|
|||
/// </returns>
|
|||
public static ColorMoment operator -(ColorMoment moment) |
|||
{ |
|||
byte pAlpha = p.Alpha; |
|||
byte pRed = p.Red; |
|||
byte pGreen = p.Green; |
|||
byte pBlue = p.Blue; |
|||
Alpha += pAlpha; |
|||
Red += pRed; |
|||
Green += pGreen; |
|||
Blue += pBlue; |
|||
Weight++; |
|||
Moment += pAlpha * pAlpha + pRed * pRed + pGreen * pGreen + pBlue * pBlue; |
|||
moment.Alpha = -moment.Alpha; |
|||
moment.Red = -moment.Red; |
|||
moment.Green = -moment.Green; |
|||
moment.Blue = -moment.Blue; |
|||
moment.Weight = -moment.Weight; |
|||
moment.Moment = -moment.Moment; |
|||
return moment; |
|||
} |
|||
|
|||
public void AddFast(ref ColorMoment c2) |
|||
/// <summary>
|
|||
/// Adds a pixel to the current instance.
|
|||
/// </summary>
|
|||
/// <param name="pixel">
|
|||
/// The pixel to add.
|
|||
/// </param>
|
|||
public void Add(Pixel pixel) |
|||
{ |
|||
Alpha += c2.Alpha; |
|||
Red += c2.Red; |
|||
Green += c2.Green; |
|||
Blue += c2.Blue; |
|||
Weight += c2.Weight; |
|||
Moment += c2.Moment; |
|||
byte alpha = pixel.Alpha; |
|||
byte red = pixel.Red; |
|||
byte green = pixel.Green; |
|||
byte blue = pixel.Blue; |
|||
this.Alpha += alpha; |
|||
this.Red += red; |
|||
this.Green += green; |
|||
this.Blue += blue; |
|||
this.Weight++; |
|||
this.Moment += (alpha * alpha) + (red * red) + (green * green) + (blue * blue); |
|||
} |
|||
|
|||
public long Amplitude() |
|||
/// <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) |
|||
{ |
|||
return Alpha * Alpha + Red * Red + Green * Green + Blue * Blue; |
|||
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 long WeightedDistance() |
|||
/// <summary>
|
|||
/// The amplitude.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// The <see cref="long"/> representing the amplitude.
|
|||
/// </returns>
|
|||
public long Amplitude() |
|||
{ |
|||
return this.Amplitude() / this.Weight; |
|||
return (this.Alpha * this.Alpha) + (this.Red * this.Red) + (this.Green * this.Green) + (this.Blue * this.Blue); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// The variance.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// The <see cref="float"/> representing the variance.
|
|||
/// </returns>
|
|||
public float Variance() |
|||
{ |
|||
float result = this.Moment - ((float)this.Amplitude() / this.Weight); |
|||
return float.IsNaN(result) ? 0.0f : result; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// The weighted distance.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// The <see cref="long"/>.
|
|||
/// </returns>
|
|||
public long WeightedDistance() |
|||
{ |
|||
return this.Amplitude() / this.Weight; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,49 @@ |
|||
// --------------------------------------------------------------------------------------------------------------------
|
|||
// <copyright file="Histogram.cs" company="James South">
|
|||
// Copyright (c) James South.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
// <summary>
|
|||
// The histogram representing the distribution of color data.
|
|||
// Adapted from <see href="https://github.com/drewnoakes" />
|
|||
// </summary>
|
|||
// --------------------------------------------------------------------------------------------------------------------
|
|||
|
|||
namespace ImageProcessor.Imaging.Quantizers.WuQuantizer |
|||
{ |
|||
using System; |
|||
|
|||
/// <summary>
|
|||
/// The histogram representing the distribution of color data.
|
|||
/// Adapted from <see href="https://github.com/drewnoakes" />
|
|||
/// </summary>
|
|||
public class Histogram |
|||
{ |
|||
/// <summary>
|
|||
/// The moments.
|
|||
/// </summary>
|
|||
internal readonly ColorMoment[,,,] Moments; |
|||
|
|||
/// <summary>
|
|||
/// The side size.
|
|||
/// </summary>
|
|||
private const int SideSize = 33; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Histogram"/> class.
|
|||
/// </summary>
|
|||
public Histogram() |
|||
{ |
|||
// 47,436,840 bytes
|
|||
this.Moments = new ColorMoment[SideSize, SideSize, SideSize, SideSize]; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// The clear.
|
|||
/// </summary>
|
|||
internal void Clear() |
|||
{ |
|||
Array.Clear(this.Moments, 0, SideSize * SideSize * SideSize * SideSize); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue