예제 #1
0
        /// <summary>
        /// Generates the quantized result.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="colorCount">The color count.</param>
        /// <param name="width">Width of image</param>
        /// <param name="height">Height of image</param>
        /// <param name="destPixels">Pixel values are written here. Must provide width*height memory.</param>
        /// <param name="padMultiple4">True to write zero padding to make row bytes multiple of 4</param>
        /// <returns>Receives colors</returns>
        private unsafe uint[] GenerateResult(uint *image, int colorCount, int width, int height, byte *destPixels, bool padMultiple4)
        {
            uint[] palette = new uint[colorCount];

            // rows must be a multiple of 4, hence padding up to 3 bytes for 8-bit indexed pixels
            int widthMod4  = width % 4;
            int widthZeros = widthMod4 != 0 ? 4 - widthMod4 : 0;

            for (int k = 0; k < colorCount; k++)
            {
                this.Mark(ref this.cube[k], (byte)k);

                float weight = WuAlphaColorQuantizer.Volume(ref this.cube[k], this.vwt);

                if (weight != 0)
                {
                    uint a = (byte)(WuAlphaColorQuantizer.Volume(ref this.cube[k], this.vma) / weight);
                    uint r = (byte)(WuAlphaColorQuantizer.Volume(ref this.cube[k], this.vmr) / weight);
                    uint g = (byte)(WuAlphaColorQuantizer.Volume(ref this.cube[k], this.vmg) / weight);
                    uint b = (byte)(WuAlphaColorQuantizer.Volume(ref this.cube[k], this.vmb) / weight);

                    palette[k] = (a << 24) | (r << 16) | (g << 8) | b;
                }
                else
                {
                    palette[k] = 0xFF000000;
                }
            }

            for (int ri = 0; ri < height; ri++)
            {
                for (int ci = 0; ci < width; ci++)
                {
                    uint pix = image[0];

                    uint a = ((pix & 0xFF000000) >> 24) >> (8 - WuAlphaColorQuantizer.IndexAlphaBits);
                    uint r = ((pix & 0x00FF0000) >> 16) >> (8 - WuAlphaColorQuantizer.IndexBits);
                    uint g = ((pix & 0x0000FF00) >> 8) >> (8 - WuAlphaColorQuantizer.IndexBits);
                    uint b = (pix & 0x000000FF) >> (8 - WuAlphaColorQuantizer.IndexBits);

                    int ind = WuAlphaColorQuantizer.GetIndex((int)r + 1, (int)g + 1, (int)b + 1, (int)a + 1);

                    destPixels[0] = this.tag[ind];
                    destPixels++;
                    image++;
                }

                // write additional zero bytes if requested
                if (padMultiple4)
                {
                    for (int c = 0; c < widthZeros; c++)
                    {
                        destPixels[0] = 0x00;
                        destPixels++;
                    }
                }
            }

            return(palette);
        }
예제 #2
0
        /// <summary>
        /// Computes the weighted variance of a box.
        /// </summary>
        /// <param name="c">The cube.</param>
        /// <returns>The result.</returns>
        private float Variance(ref Box c)
        {
            float dr = WuAlphaColorQuantizer.Volume(ref c, this.vmr);
            float dg = WuAlphaColorQuantizer.Volume(ref c, this.vmg);
            float db = WuAlphaColorQuantizer.Volume(ref c, this.vmb);
            float da = WuAlphaColorQuantizer.Volume(ref c, this.vma);

            float xx =
                this.m2[WuAlphaColorQuantizer.GetIndex(c.R1, c.G1, c.B1, c.A1)]
                - this.m2[WuAlphaColorQuantizer.GetIndex(c.R1, c.G1, c.B1, c.A0)]
                - this.m2[WuAlphaColorQuantizer.GetIndex(c.R1, c.G1, c.B0, c.A1)]
                + this.m2[WuAlphaColorQuantizer.GetIndex(c.R1, c.G1, c.B0, c.A0)]
                - this.m2[WuAlphaColorQuantizer.GetIndex(c.R1, c.G0, c.B1, c.A1)]
                + this.m2[WuAlphaColorQuantizer.GetIndex(c.R1, c.G0, c.B1, c.A0)]
                + this.m2[WuAlphaColorQuantizer.GetIndex(c.R1, c.G0, c.B0, c.A1)]
                - this.m2[WuAlphaColorQuantizer.GetIndex(c.R1, c.G0, c.B0, c.A0)]
                - this.m2[WuAlphaColorQuantizer.GetIndex(c.R0, c.G1, c.B1, c.A1)]
                + this.m2[WuAlphaColorQuantizer.GetIndex(c.R0, c.G1, c.B1, c.A0)]
                + this.m2[WuAlphaColorQuantizer.GetIndex(c.R0, c.G1, c.B0, c.A1)]
                - this.m2[WuAlphaColorQuantizer.GetIndex(c.R0, c.G1, c.B0, c.A0)]
                + this.m2[WuAlphaColorQuantizer.GetIndex(c.R0, c.G0, c.B1, c.A1)]
                - this.m2[WuAlphaColorQuantizer.GetIndex(c.R0, c.G0, c.B1, c.A0)]
                - this.m2[WuAlphaColorQuantizer.GetIndex(c.R0, c.G0, c.B0, c.A1)]
                + this.m2[WuAlphaColorQuantizer.GetIndex(c.R0, c.G0, c.B0, c.A0)];

            return(xx - (((dr * dr) + (dg * dg) + (db * db) + (da * da)) / WuAlphaColorQuantizer.Volume(ref c, this.vwt)));
        }
예제 #3
0
        /// <summary>
        /// Builds a 3-D color histogram of <c>counts, r/g/b, c^2</c>.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="width">Width of image</param>
        /// <param name="height">Height of image</param>
        private unsafe void Build3DHistogram(uint *image, int width, int height)
        {
            int pixels = width * height;

            for (int i = 0; i < pixels; i++)
            {
                uint pix = image[i];
                int  a   = (int)((pix & 0xFF000000) >> 24);
                int  r   = (int)((pix & 0x00FF0000) >> 16);
                int  g   = (int)((pix & 0x0000FF00) >> 8);
                int  b   = (int)(pix & 0x000000FF);

                int inr = r >> (8 - WuAlphaColorQuantizer.IndexBits);
                int ing = g >> (8 - WuAlphaColorQuantizer.IndexBits);
                int inb = b >> (8 - WuAlphaColorQuantizer.IndexBits);
                int ina = a >> (8 - WuAlphaColorQuantizer.IndexAlphaBits);

                int ind = WuAlphaColorQuantizer.GetIndex((int)inr + 1, (int)ing + 1, (int)inb + 1, (int)ina + 1);

                this.vwt[ind]++;
                this.vmr[ind] += r;
                this.vmg[ind] += g;
                this.vmb[ind] += b;
                this.vma[ind] += a;
                this.m2[ind]  += (r * r) + (g * g) + (b * b) + (a * a);
            }
        }
예제 #4
0
        /// <summary>
        /// Computes the weighted variance of a box.
        /// </summary>
        /// <param name="cube">The cube.</param>
        /// <returns>The result.</returns>
        private double Variance(Box cube)
        {
            double dr = WuAlphaColorQuantizer.Volume(cube, this.vmr);
            double dg = WuAlphaColorQuantizer.Volume(cube, this.vmg);
            double db = WuAlphaColorQuantizer.Volume(cube, this.vmb);
            double da = WuAlphaColorQuantizer.Volume(cube, this.vma);

            double xx =
                this.m2[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G1, cube.B1, cube.A1)]
                - this.m2[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G1, cube.B1, cube.A0)]
                - this.m2[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G1, cube.B0, cube.A1)]
                + this.m2[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G1, cube.B0, cube.A0)]
                - this.m2[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, cube.B1, cube.A1)]
                + this.m2[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, cube.B1, cube.A0)]
                + this.m2[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, cube.B0, cube.A1)]
                - this.m2[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, cube.B0, cube.A0)]
                - this.m2[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, cube.B1, cube.A1)]
                + this.m2[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, cube.B1, cube.A0)]
                + this.m2[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, cube.B0, cube.A1)]
                - this.m2[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, cube.B0, cube.A0)]
                + this.m2[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B1, cube.A1)]
                - this.m2[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B1, cube.A0)]
                - this.m2[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B0, cube.A1)]
                + this.m2[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B0, cube.A0)];

            return(xx - (((dr * dr) + (dg * dg) + (db * db) + (da * da)) / WuAlphaColorQuantizer.Volume(cube, this.vwt)));
        }
예제 #5
0
        private static int Top(ref Box cube, int direction, int position, int[] moment)
        {
            switch (direction)
            {
            // Red
            case 3:
                return(moment[WuAlphaColorQuantizer.GetIndex(position, cube.G1, cube.B1, cube.A1)]
                       - moment[WuAlphaColorQuantizer.GetIndex(position, cube.G1, cube.B1, cube.A0)]
                       - moment[WuAlphaColorQuantizer.GetIndex(position, cube.G1, cube.B0, cube.A1)]
                       + moment[WuAlphaColorQuantizer.GetIndex(position, cube.G1, cube.B0, cube.A0)]
                       - moment[WuAlphaColorQuantizer.GetIndex(position, cube.G0, cube.B1, cube.A1)]
                       + moment[WuAlphaColorQuantizer.GetIndex(position, cube.G0, cube.B1, cube.A0)]
                       + moment[WuAlphaColorQuantizer.GetIndex(position, cube.G0, cube.B0, cube.A1)]
                       - moment[WuAlphaColorQuantizer.GetIndex(position, cube.G0, cube.B0, cube.A0)]);

            // Green
            case 2:
                return(moment[WuAlphaColorQuantizer.GetIndex(cube.R1, position, cube.B1, cube.A1)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R1, position, cube.B1, cube.A0)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R1, position, cube.B0, cube.A1)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R1, position, cube.B0, cube.A0)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R0, position, cube.B1, cube.A1)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, position, cube.B1, cube.A0)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, position, cube.B0, cube.A1)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R0, position, cube.B0, cube.A0)]);

            // Blue
            case 1:
                return(moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G1, position, cube.A1)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G1, position, cube.A0)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, position, cube.A1)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, position, cube.A0)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, position, cube.A1)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, position, cube.A0)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, position, cube.A1)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, position, cube.A0)]);

            // Alpha
            case 0:
                return(moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G1, cube.B1, position)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G1, cube.B0, position)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, cube.B1, position)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, cube.B0, position)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, cube.B1, position)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, cube.B0, position)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B1, position)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B0, position)]);

            default:
                throw new ArgumentOutOfRangeException("direction");
            }
        }
        /// <summary>
        /// Computes part of Volume(cube, moment) that doesn't depend on r1, g1, or b1 (depending on direction).
        /// </summary>
        /// <param name="cube">The cube.</param>
        /// <param name="direction">The direction.</param>
        /// <param name="moment">The moment.</param>
        /// <returns>The result.</returns>
        private static long Bottom(Box cube, int direction, long[] moment)
        {
            switch (direction)
            {
            // Red
            case 3:
                return(-moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, cube.B1, cube.A1)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, cube.B1, cube.A0)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, cube.B0, cube.A1)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, cube.B0, cube.A0)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B1, cube.A1)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B1, cube.A0)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B0, cube.A1)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B0, cube.A0)]);

            // Green
            case 2:
                return(-moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, cube.B1, cube.A1)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, cube.B1, cube.A0)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, cube.B0, cube.A1)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, cube.B0, cube.A0)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B1, cube.A1)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B1, cube.A0)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B0, cube.A1)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B0, cube.A0)]);

            // Blue
            case 1:
                return(-moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G1, cube.B0, cube.A1)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G1, cube.B0, cube.A0)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, cube.B0, cube.A1)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, cube.B0, cube.A0)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, cube.B0, cube.A1)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, cube.B0, cube.A0)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B0, cube.A1)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B0, cube.A0)]);

            // Alpha
            case 0:
                return(-moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G1, cube.B1, cube.A0)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G1, cube.B0, cube.A0)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, cube.B1, cube.A0)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, cube.B0, cube.A0)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, cube.B1, cube.A0)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, cube.B0, cube.A0)]
                       - moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B1, cube.A0)]
                       + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B0, cube.A0)]);

            default:
                throw new ArgumentOutOfRangeException(nameof(direction));
            }
        }
예제 #7
0
 /// <summary>
 /// Marks a color space tag.
 /// </summary>
 /// <param name="c">The cube.</param>
 /// <param name="label">A label.</param>
 private void Mark(ref Box c, byte label)
 {
     for (int r = c.R0 + 1; r <= c.R1; r++)
     {
         for (int g = c.G0 + 1; g <= c.G1; g++)
         {
             for (int b = c.B0 + 1; b <= c.B1; b++)
             {
                 for (int a = c.A0 + 1; a <= c.A1; a++)
                 {
                     this.tag[WuAlphaColorQuantizer.GetIndex(r, g, b, a)] = label;
                 }
             }
         }
     }
 }
예제 #8
0
 private static float Volume(ref Box cube, int[] moment)
 {
     return((float)(moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G1, cube.B1, cube.A1)]
                    - moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G1, cube.B1, cube.A0)]
                    - moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G1, cube.B0, cube.A1)]
                    + moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G1, cube.B0, cube.A0)]
                    - moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, cube.B1, cube.A1)]
                    + moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, cube.B1, cube.A0)]
                    + moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, cube.B0, cube.A1)]
                    - moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, cube.B0, cube.A0)]
                    - moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, cube.B1, cube.A1)]
                    + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, cube.B1, cube.A0)]
                    + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, cube.B0, cube.A1)]
                    - moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, cube.B0, cube.A0)]
                    + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B1, cube.A1)]
                    - moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B1, cube.A0)]
                    - moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B0, cube.A1)]
                    + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B0, cube.A0)]));
 }
예제 #9
0
 /// <summary>
 /// Computes sum over a box of any given statistic.
 /// </summary>
 /// <param name="cube">The cube.</param>
 /// <param name="moment">The moment.</param>
 /// <returns>The result.</returns>
 private static double Volume(Box cube, long[] moment)
 {
     return(moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G1, cube.B1, cube.A1)]
            - moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G1, cube.B1, cube.A0)]
            - moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G1, cube.B0, cube.A1)]
            + moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G1, cube.B0, cube.A0)]
            - moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, cube.B1, cube.A1)]
            + moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, cube.B1, cube.A0)]
            + moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, cube.B0, cube.A1)]
            - moment[WuAlphaColorQuantizer.GetIndex(cube.R1, cube.G0, cube.B0, cube.A0)]
            - moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, cube.B1, cube.A1)]
            + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, cube.B1, cube.A0)]
            + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, cube.B0, cube.A1)]
            - moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G1, cube.B0, cube.A0)]
            + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B1, cube.A1)]
            - moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B1, cube.A0)]
            - moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B0, cube.A1)]
            + moment[WuAlphaColorQuantizer.GetIndex(cube.R0, cube.G0, cube.B0, cube.A0)]);
 }
예제 #10
0
        /// <summary>
        /// Generates the quantized result.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="colorCount">The color count.</param>
        /// <returns>The result.</returns>
        private ColorQuantizerResult GenerateResult(byte[] image, int colorCount)
        {
            var quantizedImage = new ColorQuantizerResult(image.Length / 4, colorCount);

            for (int k = 0; k < colorCount; k++)
            {
                this.Mark(ref this.cube[k], (byte)k);

                float weight = WuAlphaColorQuantizer.Volume(ref this.cube[k], this.vwt);

                if (weight != 0)
                {
                    quantizedImage.Palette[(k * 4) + 3] = (byte)(WuAlphaColorQuantizer.Volume(ref this.cube[k], this.vma) / weight);
                    quantizedImage.Palette[(k * 4) + 2] = (byte)(WuAlphaColorQuantizer.Volume(ref this.cube[k], this.vmr) / weight);
                    quantizedImage.Palette[(k * 4) + 1] = (byte)(WuAlphaColorQuantizer.Volume(ref this.cube[k], this.vmg) / weight);
                    quantizedImage.Palette[k * 4]       = (byte)(WuAlphaColorQuantizer.Volume(ref this.cube[k], this.vmb) / weight);
                }
                else
                {
                    quantizedImage.Palette[(k * 4) + 3] = 0xff;
                    quantizedImage.Palette[(k * 4) + 2] = 0;
                    quantizedImage.Palette[(k * 4) + 1] = 0;
                    quantizedImage.Palette[k * 4]       = 0;
                }
            }

            for (int i = 0; i < image.Length / 4; i++)
            {
                int a = image[(i * 4) + 3] >> (8 - WuAlphaColorQuantizer.IndexAlphaBits);
                int r = image[(i * 4) + 2] >> (8 - WuAlphaColorQuantizer.IndexBits);
                int g = image[(i * 4) + 1] >> (8 - WuAlphaColorQuantizer.IndexBits);
                int b = image[i * 4] >> (8 - WuAlphaColorQuantizer.IndexBits);

                int ind = WuAlphaColorQuantizer.GetIndex(r + 1, g + 1, b + 1, a + 1);

                quantizedImage.Bytes[i] = this.tag[ind];
            }

            return(quantizedImage);
        }
예제 #11
0
        /// <summary>
        /// Builds a 3-D color histogram of <c>counts, r/g/b, c^2</c>.
        /// </summary>
        /// <param name="image">The image.</param>
        private void Build3DHistogram(byte[] image)
        {
            for (int i = 0; i < image.Length; i += 4)
            {
                int a = image[i + 3];
                int r = image[i + 2];
                int g = image[i + 1];
                int b = image[i];

                int inr = r >> (8 - WuAlphaColorQuantizer.IndexBits);
                int ing = g >> (8 - WuAlphaColorQuantizer.IndexBits);
                int inb = b >> (8 - WuAlphaColorQuantizer.IndexBits);
                int ina = a >> (8 - WuAlphaColorQuantizer.IndexAlphaBits);

                int ind = WuAlphaColorQuantizer.GetIndex(inr + 1, ing + 1, inb + 1, ina + 1);

                this.vwt[ind]++;
                this.vmr[ind] += r;
                this.vmg[ind] += g;
                this.vmb[ind] += b;
                this.vma[ind] += a;
                this.m2[ind]  += (r * r) + (g * g) + (b * b) + (a * a);
            }
        }
예제 #12
0
        /// <summary>
        /// Converts the histogram into moments so that we can rapidly calculate
        /// the sums of the above quantities over any desired box.
        /// </summary>
        private void Get3DMoments()
        {
            for (int r = 1; r < WuAlphaColorQuantizer.IndexCount; r++)
            {
                Array.Clear(this.volume, 0, WuAlphaColorQuantizer.IndexCount * WuAlphaColorQuantizer.IndexAlphaCount);
                Array.Clear(this.volumeR, 0, WuAlphaColorQuantizer.IndexCount * WuAlphaColorQuantizer.IndexAlphaCount);
                Array.Clear(this.volumeG, 0, WuAlphaColorQuantizer.IndexCount * WuAlphaColorQuantizer.IndexAlphaCount);
                Array.Clear(this.volumeB, 0, WuAlphaColorQuantizer.IndexCount * WuAlphaColorQuantizer.IndexAlphaCount);
                Array.Clear(this.volumeA, 0, WuAlphaColorQuantizer.IndexCount * WuAlphaColorQuantizer.IndexAlphaCount);
                Array.Clear(this.volume2, 0, WuAlphaColorQuantizer.IndexCount * WuAlphaColorQuantizer.IndexAlphaCount);

                for (int g = 1; g < WuAlphaColorQuantizer.IndexCount; g++)
                {
                    Array.Clear(this.area, 0, WuAlphaColorQuantizer.IndexAlphaCount);
                    Array.Clear(this.areaR, 0, WuAlphaColorQuantizer.IndexAlphaCount);
                    Array.Clear(this.areaG, 0, WuAlphaColorQuantizer.IndexAlphaCount);
                    Array.Clear(this.areaB, 0, WuAlphaColorQuantizer.IndexAlphaCount);
                    Array.Clear(this.areaA, 0, WuAlphaColorQuantizer.IndexAlphaCount);
                    Array.Clear(this.area2, 0, WuAlphaColorQuantizer.IndexAlphaCount);

                    for (int b = 1; b < WuAlphaColorQuantizer.IndexCount; b++)
                    {
                        int   line  = 0;
                        int   lineR = 0;
                        int   lineG = 0;
                        int   lineB = 0;
                        int   lineA = 0;
                        float line2 = 0;

                        for (int a = 1; a < WuAlphaColorQuantizer.IndexAlphaCount; a++)
                        {
                            int ind1 = WuAlphaColorQuantizer.GetIndex(r, g, b, a);

                            line  += this.vwt[ind1];
                            lineR += this.vmr[ind1];
                            lineG += this.vmg[ind1];
                            lineB += this.vmb[ind1];
                            lineA += this.vma[ind1];
                            line2 += this.m2[ind1];

                            this.area[a]  += line;
                            this.areaR[a] += lineR;
                            this.areaG[a] += lineG;
                            this.areaB[a] += lineB;
                            this.areaA[a] += lineA;
                            this.area2[a] += line2;

                            int inv = (b * WuAlphaColorQuantizer.IndexAlphaCount) + a;

                            this.volume[inv]  += this.area[a];
                            this.volumeR[inv] += this.areaR[a];
                            this.volumeG[inv] += this.areaG[a];
                            this.volumeB[inv] += this.areaB[a];
                            this.volumeA[inv] += this.areaA[a];
                            this.volume2[inv] += this.area2[a];

                            int ind2 = ind1 - WuAlphaColorQuantizer.GetIndex(1, 0, 0, 0);

                            this.vwt[ind1] = this.vwt[ind2] + this.volume[inv];
                            this.vmr[ind1] = this.vmr[ind2] + this.volumeR[inv];
                            this.vmg[ind1] = this.vmg[ind2] + this.volumeG[inv];
                            this.vmb[ind1] = this.vmb[ind2] + this.volumeB[inv];
                            this.vma[ind1] = this.vma[ind2] + this.volumeA[inv];
                            this.m2[ind1]  = this.m2[ind2] + this.volume2[inv];
                        }
                    }
                }
            }
        }
예제 #13
0
        /// <summary>
        /// Converts the histogram into moments so that we can rapidly calculate
        /// the sums of the above quantities over any desired box.
        /// </summary>
        private void Get3DMoments()
        {
            long[]   volume  = new long[WuAlphaColorQuantizer.IndexCount * WuAlphaColorQuantizer.IndexAlphaCount];
            long[]   volumeR = new long[WuAlphaColorQuantizer.IndexCount * WuAlphaColorQuantizer.IndexAlphaCount];
            long[]   volumeG = new long[WuAlphaColorQuantizer.IndexCount * WuAlphaColorQuantizer.IndexAlphaCount];
            long[]   volumeB = new long[WuAlphaColorQuantizer.IndexCount * WuAlphaColorQuantizer.IndexAlphaCount];
            long[]   volumeA = new long[WuAlphaColorQuantizer.IndexCount * WuAlphaColorQuantizer.IndexAlphaCount];
            double[] volume2 = new double[WuAlphaColorQuantizer.IndexCount * WuAlphaColorQuantizer.IndexAlphaCount];

            long[]   area  = new long[WuAlphaColorQuantizer.IndexAlphaCount];
            long[]   areaR = new long[WuAlphaColorQuantizer.IndexAlphaCount];
            long[]   areaG = new long[WuAlphaColorQuantizer.IndexAlphaCount];
            long[]   areaB = new long[WuAlphaColorQuantizer.IndexAlphaCount];
            long[]   areaA = new long[WuAlphaColorQuantizer.IndexAlphaCount];
            double[] area2 = new double[WuAlphaColorQuantizer.IndexAlphaCount];

            for (int r = 1; r < WuAlphaColorQuantizer.IndexCount; r++)
            {
                Array.Clear(volume, 0, WuAlphaColorQuantizer.IndexCount * WuAlphaColorQuantizer.IndexAlphaCount);
                Array.Clear(volumeR, 0, WuAlphaColorQuantizer.IndexCount * WuAlphaColorQuantizer.IndexAlphaCount);
                Array.Clear(volumeG, 0, WuAlphaColorQuantizer.IndexCount * WuAlphaColorQuantizer.IndexAlphaCount);
                Array.Clear(volumeB, 0, WuAlphaColorQuantizer.IndexCount * WuAlphaColorQuantizer.IndexAlphaCount);
                Array.Clear(volumeA, 0, WuAlphaColorQuantizer.IndexCount * WuAlphaColorQuantizer.IndexAlphaCount);
                Array.Clear(volume2, 0, WuAlphaColorQuantizer.IndexCount * WuAlphaColorQuantizer.IndexAlphaCount);

                for (int g = 1; g < WuAlphaColorQuantizer.IndexCount; g++)
                {
                    Array.Clear(area, 0, WuAlphaColorQuantizer.IndexAlphaCount);
                    Array.Clear(areaR, 0, WuAlphaColorQuantizer.IndexAlphaCount);
                    Array.Clear(areaG, 0, WuAlphaColorQuantizer.IndexAlphaCount);
                    Array.Clear(areaB, 0, WuAlphaColorQuantizer.IndexAlphaCount);
                    Array.Clear(areaA, 0, WuAlphaColorQuantizer.IndexAlphaCount);
                    Array.Clear(area2, 0, WuAlphaColorQuantizer.IndexAlphaCount);

                    for (int b = 1; b < WuAlphaColorQuantizer.IndexCount; b++)
                    {
                        long   line  = 0;
                        long   lineR = 0;
                        long   lineG = 0;
                        long   lineB = 0;
                        long   lineA = 0;
                        double line2 = 0;

                        for (int a = 1; a < WuAlphaColorQuantizer.IndexAlphaCount; a++)
                        {
                            int ind1 = WuAlphaColorQuantizer.GetIndex(r, g, b, a);

                            line  += this.vwt[ind1];
                            lineR += this.vmr[ind1];
                            lineG += this.vmg[ind1];
                            lineB += this.vmb[ind1];
                            lineA += this.vma[ind1];
                            line2 += this.m2[ind1];

                            area[a]  += line;
                            areaR[a] += lineR;
                            areaG[a] += lineG;
                            areaB[a] += lineB;
                            areaA[a] += lineA;
                            area2[a] += line2;

                            int inv = (b * WuAlphaColorQuantizer.IndexAlphaCount) + a;

                            volume[inv]  += area[a];
                            volumeR[inv] += areaR[a];
                            volumeG[inv] += areaG[a];
                            volumeB[inv] += areaB[a];
                            volumeA[inv] += areaA[a];
                            volume2[inv] += area2[a];

                            int ind2 = ind1 - WuAlphaColorQuantizer.GetIndex(1, 0, 0, 0);

                            this.vwt[ind1] = this.vwt[ind2] + volume[inv];
                            this.vmr[ind1] = this.vmr[ind2] + volumeR[inv];
                            this.vmg[ind1] = this.vmg[ind2] + volumeG[inv];
                            this.vmb[ind1] = this.vmb[ind2] + volumeB[inv];
                            this.vma[ind1] = this.vma[ind2] + volumeA[inv];
                            this.m2[ind1]  = this.m2[ind2] + volume2[inv];
                        }
                    }
                }
            }
        }