rendered paste bodypublic XY[] findRGBCluster(RGB rgb[], Rectangle bounds, int maxMatches) { boolean filterThoseNearBy = true; long start = System.currentTimeMillis(); // calculate the tolerance for each RGB int[][] tolerances = new int[rgb.length][3]; for (int i = 0; i < rgb.length; i++) { tolerances[i][0] = getGameScreenTolerance(rgb[i].r); tolerances[i][1] = getGameScreenTolerance(rgb[i].g); tolerances[i][2] = getGameScreenTolerance(rgb[i].b); } // get the Color Map short[][][] colorMap = getColorArray2d(); // Divide the Screen into blocks int xParts = 15; int yParts = 10; float zoneDx = (float) bounds.width / xParts; float zoneDy = (float) bounds.height / yParts; // count the colors in each block int[][][] counts = new int[xParts][yParts][rgb.length]; int[] totalColorCounts = new int[rgb.length]; for (int x = 0; x < xParts; x++) { for (int y = 0; y < yParts; y++) { int xS = bounds.x + x * (int) zoneDx; int yS = bounds.y + y * (int) zoneDy; for (int k = 0; k < rgb.length; k++) { int count = numRGBs(colorMap, rgb[k], xS, yS, xS + (int) zoneDx, yS + (int) zoneDy, tolerances[k][0], tolerances[k][1], tolerances[k][2]); counts[x][y][k] = count; totalColorCounts[k] += count; } } } /* * Calulate the zones, which are 2 blocks x 2 blocks Value is based on * the (# matched colors in zone ) / (total matched colors in bounds) * Values is added for each RGB Colors are weighed equally. */ float actualZones[][] = new float[xParts - 1][yParts - 1]; float rgbWeight = (float) 1 / rgb.length; for (int x = 0; x < xParts - 1; x++) { for (int y = 0; y < yParts - 1; y++) { for (int k = 0; k < rgb.length; k++) { if (totalColorCounts[k] > 0) { int colorCount = 0; colorCount += counts[x][y][k]; colorCount += counts[x + 1][y][k]; colorCount += counts[x][y + 1][k]; colorCount += counts[x + 1][y + 1][k]; actualZones[x][y] += (rgbWeight * colorCount) / totalColorCounts[k]; } } } } // Sort the Zones into the highest count first and ignore the Zones near // previous zones boolean selected[][] = new boolean[xParts - 1][yParts - 1]; XY result[] = new XY[maxMatches]; for (int i = 0; i < maxMatches; i++) { int winnerX = -1; int winnerY = -1; double winner = -1; for (int x = 0; x < xParts - 1; x++) { for (int y = 0; y < yParts - 1; y++) { if (!selected[x][y]) { if (actualZones[x][y] > winner) { winnerX = x; winnerY = y; winner = actualZones[x][y]; } } } } if (winnerX == -1 || winnerY == -1 || winner == 0.0) { XY newResult[] = new XY[i]; System.arraycopy(result, 0, newResult, 0, i); result = newResult; break; } else { selected[winnerX][winnerY] = true; if (filterThoseNearBy) { boolean innerXinRange = winnerX - 1 != -1; boolean outerXinRange = winnerX + 1 != xParts - 1; boolean outerYinRange = winnerY + 1 != yParts - 1; boolean innerYinRange = winnerY - 1 != -1; if (outerXinRange) { selected[winnerX + 1][winnerY] = true; // if (outerYinRange) { // selected[winnerX + 1][winnerY + 1] = true; // } // if (innerYinRange) { // selected[winnerX + 1][winnerY - 1] = true; // } } if (innerXinRange) { selected[winnerX - 1][winnerY] = true; // if (outerYinRange) { // selected[winnerX - 1][winnerY + 1] = true; // } // if (innerYinRange) { // selected[winnerX - 1][winnerY - 1] = true; // } } if (outerYinRange) { selected[winnerX][winnerY + 1] = true; } if (innerYinRange) { selected[winnerX][winnerY - 1] = true; } } // find the Most Dense 6px x 6px part in the Zone final int minX = bounds.x + (int) (zoneDx * winnerX); final int minY = bounds.y + (int) (zoneDy * winnerY); final int maxX = bounds.x + (int) (zoneDx * (winnerX + 2)); final int maxY = bounds.y + (int) (zoneDy * (winnerY + 2)); final int interval = 6; int smallerWinnerX = -1; int smallerWinnerY = -1; int smallerWinnerCount = -1; for (int x = minX; x < maxX; x += interval) { for (int y = minY; y < maxY; y += interval) { int count = 0; for (int k = 0; k < rgb.length; k++) { count += numRGBs(colorMap, rgb[k], x, y, x + interval, y + interval, tolerances[k][0], tolerances[k][1], tolerances[k][2]); } if (count > smallerWinnerCount) { smallerWinnerX = x + interval / 2; smallerWinnerY = y + interval / 2; smallerWinnerCount = count; } } } final int smallerWinnerXcopy = smallerWinnerX; final int smallerWinnerYcopy = smallerWinnerY; // System.out.println("dx="+(minX-smallerWinnerX)+" // dy="+(minY-smallerWinnerY)); result[i] = new XY(smallerWinnerX, smallerWinnerY); if (SettingsManager.debug) { addPaintJob(new PaintJob() { long start = System.currentTimeMillis(); @Override public void paint(Graphics g) { g.setColor(Color.blue); g.drawRect(minX, minY, maxX - minX, maxY - minY); g.setColor(Color.green); g.drawRect(smallerWinnerXcopy, smallerWinnerYcopy, 1, 1); } @Override public boolean timeUp() { return start + 5000 < System.currentTimeMillis(); } }); paintText(result[i].x, result[i].y, i + "", 5000, Color.WHITE); } } } if (SettingsManager.debug) { paintText(Areas.GAME.x + Areas.GAME.width, 20, "findRGBsCluster() " + (System.currentTimeMillis() - start), 5000, Color.WHITE); log("findRGBsCluster() took" + (System.currentTimeMillis() - start)); } return result; }