mirror of https://github.com/SixLabors/ImageSharp
Browse Source
Former-commit-id: 12814847839fad273c06fd6a12d04629fed37f59 Former-commit-id: 169e61fbe889a6de7c3a4a8e51eaa53af79839bdaf/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 |
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 |
internal struct ColorMoment |
||||
{ |
{ |
||||
|
/// <summary>
|
||||
|
/// The alpha.
|
||||
|
/// </summary>
|
||||
public long Alpha; |
public long Alpha; |
||||
public long Red; |
|
||||
public long Green; |
/// <summary>
|
||||
|
/// The blue.
|
||||
|
/// </summary>
|
||||
public long Blue; |
public long Blue; |
||||
public int Weight; |
|
||||
|
/// <summary>
|
||||
|
/// The green.
|
||||
|
/// </summary>
|
||||
|
public long Green; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The moment.
|
||||
|
/// </summary>
|
||||
public float Moment; |
public float Moment; |
||||
|
|
||||
public static ColorMoment operator +(ColorMoment c1, ColorMoment c2) |
/// <summary>
|
||||
{ |
/// The red.
|
||||
c1.Alpha += c2.Alpha; |
/// </summary>
|
||||
c1.Red += c2.Red; |
public long Red; |
||||
c1.Green += c2.Green; |
|
||||
c1.Blue += c2.Blue; |
|
||||
c1.Weight += c2.Weight; |
|
||||
c1.Moment += c2.Moment; |
|
||||
return c1; |
|
||||
} |
|
||||
|
|
||||
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; |
firstAddend.Alpha += secondAddend.Alpha; |
||||
c1.Red -= c2.Red; |
firstAddend.Red += secondAddend.Red; |
||||
c1.Green -= c2.Green; |
firstAddend.Green += secondAddend.Green; |
||||
c1.Blue -= c2.Blue; |
firstAddend.Blue += secondAddend.Blue; |
||||
c1.Weight -= c2.Weight; |
firstAddend.Weight += secondAddend.Weight; |
||||
c1.Moment -= c2.Moment; |
firstAddend.Moment += secondAddend.Moment; |
||||
return c1; |
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; |
minuend.Alpha -= subtrahend.Alpha; |
||||
c1.Red = -c1.Red; |
minuend.Red -= subtrahend.Red; |
||||
c1.Green = -c1.Green; |
minuend.Green -= subtrahend.Green; |
||||
c1.Blue = -c1.Blue; |
minuend.Blue -= subtrahend.Blue; |
||||
c1.Weight = -c1.Weight; |
minuend.Weight -= subtrahend.Weight; |
||||
c1.Moment = -c1.Moment; |
minuend.Moment -= subtrahend.Moment; |
||||
return c1; |
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; |
moment.Alpha = -moment.Alpha; |
||||
byte pRed = p.Red; |
moment.Red = -moment.Red; |
||||
byte pGreen = p.Green; |
moment.Green = -moment.Green; |
||||
byte pBlue = p.Blue; |
moment.Blue = -moment.Blue; |
||||
Alpha += pAlpha; |
moment.Weight = -moment.Weight; |
||||
Red += pRed; |
moment.Moment = -moment.Moment; |
||||
Green += pGreen; |
return moment; |
||||
Blue += pBlue; |
|
||||
Weight++; |
|
||||
Moment += pAlpha * pAlpha + pRed * pRed + pGreen * pGreen + pBlue * pBlue; |
|
||||
} |
} |
||||
|
|
||||
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; |
byte alpha = pixel.Alpha; |
||||
Red += c2.Red; |
byte red = pixel.Red; |
||||
Green += c2.Green; |
byte green = pixel.Green; |
||||
Blue += c2.Blue; |
byte blue = pixel.Blue; |
||||
Weight += c2.Weight; |
this.Alpha += alpha; |
||||
Moment += c2.Moment; |
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() |
public float Variance() |
||||
{ |
{ |
||||
float result = this.Moment - ((float)this.Amplitude() / this.Weight); |
float result = this.Moment - ((float)this.Amplitude() / this.Weight); |
||||
return float.IsNaN(result) ? 0.0f : result; |
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