SimilarityUtils { public static double calcSimilarityByFeatureMatrix(BufferedImage expectedImage, BufferedImage actualImage, Rectangle rectangle, Offset offset) { CalcSimilarityPrep prep = prepareCalcSimilarity(expectedImage, actualImage, rectangle, offset); int GridWidth = prep.actualWidth / FeatureCol, GridHeight = prep.actualHeight / FeatureRow; int GridArea = GridWidth * GridHeight; Color[][] actualFeature = new Color[FeatureRow][FeatureCol]; for (int row = 0; row < FeatureRow; row++) { for (int col = 0; col < FeatureCol; col++) { int rSum = 0, gSum = 0, bSum = 0; for (int i = 0; i < GridHeight; i++) { for (int j = 0; j < GridWidth; j++) { rSum += prep.actualRed[prep.actualWidth * (GridHeight * row + i) + (GridWidth * col + j)]; gSum += prep.actualGreen[prep.actualWidth * (GridHeight * row + i) + (GridWidth * col + j)]; bSum += prep.actualBlue[prep.actualWidth * (GridHeight * row + i) + (GridWidth * col + j)]; } } actualFeature[row][col] = new Color(rSum / GridArea, gSum / GridArea, bSum / GridArea); } } Color[][] expectedFeature = new Color[FeatureRow][FeatureCol]; int bestX = 0, bestY = 0; double dist = 0, min = -1; for (int y = 0; y <= Math.max(0, prep.topMove + prep.downMove); y++) { for (int x = 0; x <= Math.max(0, prep.leftMove + prep.rightMove); x++) { for (int row = 0; row < FeatureRow; row++) { for (int col = 0; col < FeatureCol; col++) { int rSum = 0, gSum = 0, bSum = 0; for (int i = 0; i < GridHeight; i++) { for (int j = 0; j < GridWidth; j++) { rSum += prep.expectedRed[prep.expectedWidth * (GridHeight * row + (y + i)) + (GridWidth * col + (x + j))]; gSum += prep.expectedGreen[prep.expectedWidth * (GridHeight * row + (y + i)) + (GridWidth * col + (x + j))]; bSum += prep.expectedBlue[prep.expectedWidth * (GridHeight * row + (y + i)) + (GridWidth * col + (x + j))]; } } expectedFeature[row][col] = new Color(rSum / GridArea, gSum / GridArea, bSum / GridArea); } } dist = calcFeatureDistance(expectedFeature, actualFeature); if (dist < min || min == -1) { min = dist; bestX = prep.leftMove - x; bestY = prep.topMove - y; } } } if (offset == null) { offset = new Offset(0, 0); } if (prep.maxMove != 0) { offset.setX(bestX); offset.setY(bestY); } double similarity = 1 - min; similarity = Math.floor(similarity * 100) / 100; return similarity; } private  SimilarityUtils(); static SimilarityUnit calcSimilarity(BufferedImage expectedImage, BufferedImage actualImage,
			Rectangle rectangle, ComparedRectangleArea similarRectangle, Offset offset); static SimilarityUnit calcSimilarity(BufferedImage expectedImage, BufferedImage actualImage,
			Rectangle rectangle, ComparedRectangleArea similarRectangle, Offset offset, double similarityFeatureMatrix); static double calcFeatureDistance(Color[][] expectedFeature, Color[][] actualFeature); static boolean checkFeatureSize(int width, int height); static double calcSimilarityByFeatureMatrix(BufferedImage expectedImage, BufferedImage actualImage,
			Rectangle rectangle, Offset offset); static double calcSimilarityByFeatureMatrix(BufferedImage expectedImage, BufferedImage actualImage,
			Rectangle expectedFrame, Rectangle actualFrame); static SimilarityUnit calcSimilarityPixelByPixel(BufferedImage expectedImage, BufferedImage actualImage,
			Rectangle rectangle, Offset offset);  }
@Test public void testCalcSimilarityByFeatureMatrix() throws Exception { BufferedImage image1 = ImageIO.read(getClass().getResource("hifive_logo.png")); BufferedImage image2 = ImageIO.read(getClass().getResource("hifive_logo.png")); Rectangle rectangle = new Rectangle(0, 0, image1.getWidth(), image1.getHeight()); Offset offset = new Offset(0, 0); double actual; actual = SimilarityUtils.calcSimilarityByFeatureMatrix(image1, image2, rectangle, offset); assertThat(actual, is(1.0)); Rectangle frame1 = new Rectangle(0, 0, image1.getWidth(), image1.getHeight()); Rectangle frame2 = new Rectangle(0, 0, image2.getWidth(), image2.getHeight()); actual = SimilarityUtils.calcSimilarityByFeatureMatrix(image1, image2, frame1, frame2); assertThat(actual, is(1.0)); }
@Test public void testCalcSimilarityByFeatureMatrixWithDiff() throws Exception { BufferedImage image1 = ImageIO.read(getClass().getResource("hifive_logo.png")); BufferedImage image2 = ImageIO.read(getClass().getResource("hifive_logo_similar.png")); Rectangle rectangle = new Rectangle(0, 0, image1.getWidth(), image1.getHeight()); Offset offset = new Offset(0, 0); double actual; actual = SimilarityUtils.calcSimilarityByFeatureMatrix(image1, image2, rectangle, offset); assertThat(actual, is(0.97)); Rectangle frame1 = new Rectangle(0, 0, image1.getWidth(), image1.getHeight()); Rectangle frame2 = new Rectangle(0, 0, image2.getWidth(), image2.getHeight()); actual = SimilarityUtils.calcSimilarityByFeatureMatrix(image1, image2, frame1, frame2); assertThat(actual, is(0.97)); }