예제 #1
0
        public double GetVariance()
        {
            double dr = GetPartialVolume(1);
            double dg = GetPartialVolume(2);
            double db = GetPartialVolume(3);
            double da = GetPartialVolume(4);

            double xx =
                _histogram.M2[WuCommon.GetIndex(R1, G1, B1, A1, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                - _histogram.M2[WuCommon.GetIndex(R1, G1, B1, A0, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                - _histogram.M2[WuCommon.GetIndex(R1, G1, B0, A1, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                + _histogram.M2[WuCommon.GetIndex(R1, G1, B0, A0, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                - _histogram.M2[WuCommon.GetIndex(R1, G0, B1, A1, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                + _histogram.M2[WuCommon.GetIndex(R1, G0, B1, A0, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                + _histogram.M2[WuCommon.GetIndex(R1, G0, B0, A1, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                - _histogram.M2[WuCommon.GetIndex(R1, G0, B0, A0, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                - _histogram.M2[WuCommon.GetIndex(R0, G1, B1, A1, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                + _histogram.M2[WuCommon.GetIndex(R0, G1, B1, A0, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                + _histogram.M2[WuCommon.GetIndex(R0, G1, B0, A1, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                - _histogram.M2[WuCommon.GetIndex(R0, G1, B0, A0, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                + _histogram.M2[WuCommon.GetIndex(R0, G0, B1, A1, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                - _histogram.M2[WuCommon.GetIndex(R0, G0, B1, A0, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                - _histogram.M2[WuCommon.GetIndex(R0, G0, B0, A1, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                + _histogram.M2[WuCommon.GetIndex(R0, G0, B0, A0, _histogram.IndexBits, _histogram.IndexAlphaBits)];

            return(xx - (((dr * dr) + (dg * dg) + (db * db) + (da * da)) / GetPartialVolume(5)));
        }
예제 #2
0
        private long Bottom(int direction, long[] moment)
        {
            switch (direction)
            {
            // Red
            case 3:
                return(-moment[WuCommon.GetIndex(R0, G1, B1, A1, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                       + moment[WuCommon.GetIndex(R0, G1, B1, A0, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                       + moment[WuCommon.GetIndex(R0, G1, B0, A1, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                       - moment[WuCommon.GetIndex(R0, G1, B0, A0, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                       + moment[WuCommon.GetIndex(R0, G0, B1, A1, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                       - moment[WuCommon.GetIndex(R0, G0, B1, A0, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                       - moment[WuCommon.GetIndex(R0, G0, B0, A1, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                       + moment[WuCommon.GetIndex(R0, G0, B0, A0, _histogram.IndexBits, _histogram.IndexAlphaBits)]);

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

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

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

            default:
                throw new ArgumentOutOfRangeException(nameof(direction));
            }
        }
예제 #3
0
        public static WuColorCube Create(Wu3DHistogram histogram, int colorCount)
        {
            var boxes = new WuColorBox[colorCount];

            double[] vv = new double[colorCount];

            for (int i = 0; i < colorCount; i++)
            {
                boxes[i] = new WuColorBox(histogram);
            }

            boxes[0].R0 = boxes[0].G0 = boxes[0].B0 = boxes[0].A0 = 0;
            boxes[0].R1 = boxes[0].G1 = boxes[0].B1 = histogram.IndexCount - 1;
            boxes[0].A1 = histogram.IndexAlphaCount - 1;

            int next = 0;

            for (int i = 1; i < colorCount; i++)
            {
                if (WuCommon.Cut(boxes[next], boxes[i]))
                {
                    vv[next] = boxes[next].Volume > 1 ? boxes[next].GetVariance() : 0.0;
                    vv[i]    = boxes[i].Volume > 1 ? boxes[i].GetVariance() : 0.0;
                }
                else
                {
                    vv[next] = 0.0;
                    i--;
                }

                next = 0;

                double temp = vv[0];
                for (int k = 1; k <= i; k++)
                {
                    if (vv[k] > temp)
                    {
                        temp = vv[k];
                        next = k;
                    }
                }

                if (temp <= 0.0)
                {
                    colorCount = i + 1;
                    break;
                }
            }

            return(new WuColorCube(boxes, colorCount));
        }
예제 #4
0
        public double GetPartialVolume(int direction)
        {
            long[] moment;
            switch (direction)
            {
            case 1:
                moment = _histogram.Vmr;
                break;

            case 2:
                moment = _histogram.Vmg;
                break;

            case 3:
                moment = _histogram.Vmb;
                break;

            case 4:
                moment = _histogram.Vma;
                break;

            case 5:
                moment = _histogram.Vwt;
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(direction));
            }

            return(moment[WuCommon.GetIndex(R1, G1, B1, A1, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                   - moment[WuCommon.GetIndex(R1, G1, B1, A0, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                   - moment[WuCommon.GetIndex(R1, G1, B0, A1, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                   + moment[WuCommon.GetIndex(R1, G1, B0, A0, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                   - moment[WuCommon.GetIndex(R1, G0, B1, A1, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                   + moment[WuCommon.GetIndex(R1, G0, B1, A0, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                   + moment[WuCommon.GetIndex(R1, G0, B0, A1, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                   - moment[WuCommon.GetIndex(R1, G0, B0, A0, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                   - moment[WuCommon.GetIndex(R0, G1, B1, A1, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                   + moment[WuCommon.GetIndex(R0, G1, B1, A0, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                   + moment[WuCommon.GetIndex(R0, G1, B0, A1, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                   - moment[WuCommon.GetIndex(R0, G1, B0, A0, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                   + moment[WuCommon.GetIndex(R0, G0, B1, A1, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                   - moment[WuCommon.GetIndex(R0, G0, B1, A0, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                   - moment[WuCommon.GetIndex(R0, G0, B0, A1, _histogram.IndexBits, _histogram.IndexAlphaBits)]
                   + moment[WuCommon.GetIndex(R0, G0, B0, A0, _histogram.IndexBits, _histogram.IndexAlphaBits)]);
        }
예제 #5
0
        private void FillTables(IList <Color> colors)
        {
            foreach (var color in colors)
            {
                int a = color.A;
                int r = color.R;
                int g = color.G;
                int b = color.B;

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

                int ind = WuCommon.GetIndex(inr + 1, ing + 1, inb + 1, ina + 1, IndexBits, IndexAlphaBits);

                Vwt[ind]++;
                Vmr[ind] += r;
                Vmg[ind] += g;
                Vmb[ind] += b;
                Vma[ind] += a;
                M2[ind]  += r * r + g * g + b * b + a * a;     // Euclidean distance as moment
            }
        }
예제 #6
0
        private void FillTables(Color[] colors)
        {
            for (int i = 0; i < colors.Length; i += 4)
            {
                int a = colors[i].A;
                int r = colors[i].R;
                int g = colors[i].G;
                int b = colors[i].B;

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

                int ind = WuCommon.GetIndex(inr + 1, ing + 1, inb + 1, ina + 1, IndexBits, IndexAlphaBits);

                Vwt[ind]++;
                Vmr[ind] += r;
                Vmg[ind] += g;
                Vmb[ind] += b;
                Vma[ind] += a;
                M2[ind]  += r * r + g * g + b * b + a * a;     // Euclidean distance as moment
            }
        }
예제 #7
0
        private void CalculateMoments()
        {
            long[]   volume  = new long[IndexCount * IndexAlphaCount];
            long[]   volumeR = new long[IndexCount * IndexAlphaCount];
            long[]   volumeG = new long[IndexCount * IndexAlphaCount];
            long[]   volumeB = new long[IndexCount * IndexAlphaCount];
            long[]   volumeA = new long[IndexCount * IndexAlphaCount];
            double[] volume2 = new double[IndexCount * IndexAlphaCount];

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

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

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

                    for (int b = 1; b < 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 < IndexAlphaCount; a++)
                        {
                            int ind1 = WuCommon.GetIndex(r, g, b, a, IndexBits, IndexAlphaBits);

                            line  += Vwt[ind1];
                            lineR += Vmr[ind1];
                            lineG += Vmg[ind1];
                            lineB += Vmb[ind1];
                            lineA += Vma[ind1];
                            line2 += M2[ind1];

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

                            int inv = b * 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 - WuCommon.GetIndex(1, 0, 0, 0, IndexBits, IndexAlphaBits);

                            Vwt[ind1] = Vwt[ind2] + volume[inv];
                            Vmr[ind1] = Vmr[ind2] + volumeR[inv];
                            Vmg[ind1] = Vmg[ind2] + volumeG[inv];
                            Vmb[ind1] = Vmb[ind2] + volumeB[inv];
                            Vma[ind1] = Vma[ind2] + volumeA[inv];
                            M2[ind1]  = M2[ind2] + volume2[inv];
                        }
                    }
                }
            }
        }