sclass G22MakeMaskCorrelationMatrix is MakesBufferedImage { settable long[][] imagesH; settable long[][] imagesW; // size w()*h(), every entry is a pixel diff count gettable int[] matrix; selfType images(long[][] images) { ret imagesW(images).imagesH(images); } selfType images(L images) { ret images(toArray(long[].class, images)); } public int w() { ret imagesH.length; } public int h() { ret imagesW.length; } int maxPixelDiff() { ret l(first(imagesW))*64; } bool symmetrical() { ret imagesW == imagesH; } run { int w = w(), h = h(); var matrix = this.matrix = new int[w*h]; int i = 0; if (symmetrical()) for y to h: { long[] imageH = imagesH[y]; // mirror along diagonal int x = 0, i2 = y; for (; x < y; x++, i2 += w) matrix[i++] = matrix[i2]; for (; x < w; x++) matrix[i++] = countDifferingBits(imageH, imagesW[x]); } else for y to h: { long[] imageH = imagesH[y]; for x to w: matrix[i++] = countDifferingBits(imageH, imagesW[x]); } } FloatBWImage get() { if (matrix == null) run(); int w = w(), h = h(); float max = maxPixelDiff(); ret floatBWImageFromFunction(w, h, (x, y) -> 1f-matrix[y*w+x]/max); } public BufferedImage getBufferedImage() { ret toBufferedImage (get()); } }