int xMin = Integer.MAX_VALUE; int xMax = Integer.MIN_VALUE; int yMin = Integer.MAX_VALUE; int yMax = Integer.MIN_VALUE;  double dx; double dy;   double n00 = (double) dim / (double) (unit * unit); double n01 = 0d; double n02 = 0d; double n03 = 0d; double n10 = 0d; double n11 = 0d; double n12 = 0d; double n20 = 0d; double n21 = 0d; double n30 = 0d;   double w = dim; double w2 = w * w; double w3 = Math.sqrt(w * w * w * w * w);   for (int i = dim - 1; i >= 0; i--) { n10 += x[i]; n01 += y[i]; } n10 /= dim; n01 /= dim;   for (int i = dim - 1; i >= 0; i--) { int xx = x[i]; if (xx < xMin) { xMin = xx; } if (xx > xMax) { xMax = xx; } int yy = y[i]; if (yy < yMin) { yMin = yy; } if (yy > yMax) { yMax = yy; } }  for (int i = dim - 1; i >= 0; i--) { dx = x[i] - n10; dy = y[i] - n01; n11 += (dx * dy); n12 += (dx * dy * dy); n21 += (dx * dx * dy); n20 += (dx * dx); n02 += (dy * dy); n30 += (dx * dx * dx); n03 += (dy * dy * dy); }     n11 /= w2; n20 /= w2; n02 /= w2;   n12 /= w3; n21 /= w3; n30 /= w3; n03 /= w3;    k[0] = n00; k[1] = (double) (xMax - xMin + 1) / unit; k[2] = (double) (yMax - yMin + 1) / unit; k[3] = n20; k[4] = n11; k[5] = n02; k[6] = n30; k[7] = n21; k[8] = n12; k[9] = n03;    k[10] = n20 + n02;  k[11] = ((n20 - n02) * (n20 - n02)) + (4 * n11 * n11);  k[12] = ((n30 - (3 * n12)) * (n30 - (3 * n12))) + ((n03 - (3 * n21)) * (n03 - (3 * n21)));  k[13] = ((n30 + n12) * (n30 + n12)) + ((n03 + n21) * (n03 + n21));  k[14] = ((n30 - (3 * n12)) * (n30 + n12) * (((n30 + n12) * (n30 + n12)) - (3 * (n21 + n03) * (n21 + n03)))) + ((n03 - (3 * n21)) * (n03 + n21) * (((n03 + n21) * (n03 + n21)) - (3 * (n12 + n30) * (n12 + n30))));  k[15] = ((n20 - n02) * (((n30 + n12) * (n30 + n12)) - ((n03 + n21) * (n03 + n21)))) + (4 * n11 * (n30 + n12) * (n03 + n21));  k[16] = (((3 * n21) - n03) * (n30 + n12) * (((n30 + n12) * (n30 + n12)) - (3 * (n21 + n03) * (n21 + n03)))) - (((3 * n12) - n30) * (n03 + n21) * (((n03 + n21) * (n03 + n21)) - (3 * (n12 + n30) * (n12 + n30))));    k[17] = n10; k[18] = n01;
    public Moments (int[] x,                    int[] y,                    int dim,                    int unit)    {        int xMin = Integer.MAX_VALUE;        int xMax = Integer.MIN_VALUE;        int yMin = Integer.MAX_VALUE;        int yMax = Integer.MIN_VALUE;        double dx;        double dy;        // Normalized Moments        double n00 = (double) dim / (double) (unit * unit);        double n01 = 0d;        double n02 = 0d;        double n03 = 0d;        double n10 = 0d;        double n11 = 0d;        double n12 = 0d;        double n20 = 0d;        double n21 = 0d;        double n30 = 0d;        // Total weight        double w = dim;   // For p+q = 0        double w2 = w * w; // For p+q = 2        double w3 = Math.sqrt(w * w * w * w * w); // For p+q = 3        // Mean x & y        for (int i = dim - 1; i >= 0; i--) {            n10 += x[i];            n01 += y[i];        }        n10 /= dim;        n01 /= dim;        // width & height        for (int i = dim - 1; i >= 0; i--) {            int xx = x[i];            if (xx < xMin) {                xMin = xx;            }            if (xx > xMax) {                xMax = xx;            }            int yy = y[i];            if (yy < yMin) {                yMin = yy;            }            if (yy > yMax) {                yMax = yy;            }        }        for (int i = dim - 1; i >= 0; i--) {            dx = x[i] - n10;            dy = y[i] - n01;            n11 += (dx * dy);            n12 += (dx * dy * dy);            n21 += (dx * dx * dy);            n20 += (dx * dx);            n02 += (dy * dy);            n30 += (dx * dx * dx);            n03 += (dy * dy * dy);        }        // Normalize        //        // p + q = 2        n11 /= w2;        n20 /= w2;        n02 /= w2;        //        // p + q = 3        n12 /= w3;        n21 /= w3;        n30 /= w3;        n03 /= w3;        // Assign non-orthogonal centralized moments        // (invariant to translation & scaling)        k[0] = n00; // Weight        k[1] = (double) (xMax - xMin + 1) / unit; // Width        k[2] = (double) (yMax - yMin + 1) / unit; // Height        k[3] = n20; // X absolute eccentricity        k[4] = n11; // XY covariance        k[5] = n02; // Y absolute eccentricity        k[6] = n30; // X signed eccentricity        k[7] = n21; //        k[8] = n12; //        k[9] = n03; // Y signed eccentricity        //        // Assign orthogonals moments (Hu set)        // (Invariant to translation / scaling / rotation)        k[10] = n20 + n02;        //        k[11] = ((n20 - n02) * (n20 - n02)) + (4 * n11 * n11);        //        k[12] =            ((n30 - (3 * n12)) * (n30 - (3 * n12))) +            ((n03 - (3 * n21)) * (n03 - (3 * n21)));        //        k[13] =            ((n30 + n12) * (n30 + n12)) +            ((n03 + n21) * (n03 + n21));        //        k[14] =            ((n30 - (3 * n12))             * (n30 + n12)             * (((n30 + n12) * (n30 + n12)) - (3 * (n21 + n03) * (n21 + n03)))) +            ((n03 - (3 * n21))             * (n03 + n21)             * (((n03 + n21) * (n03 + n21)) - (3 * (n12 + n30) * (n12 + n30))));        //        k[15] =            ((n20 - n02)             * (((n30 + n12) * (n30 + n12)) - ((n03 + n21) * (n03 + n21)))) +            (4 * n11 * (n30 + n12) * (n03 + n21));        //        k[16] =            (((3 * n21) - n03)             * (n30 + n12)             * (((n30 + n12) * (n30 + n12)) - (3 * (n21 + n03) * (n21 + n03)))) -            (((3 * n12) - n30)             * (n03 + n21)             * (((n03 + n21) * (n03 + n21)) - (3 * (n12 + n30) * (n12 + n30))));        // Mass center placed here        k[17] = n10; // xBar        k[18] = n01; // yBar    }