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))); }
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)); } }
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)]); }
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 } }
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 } }
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]; } } } } }