SimilarityUtils { public static SimilarityUnit calcSimilarityPixelByPixel(BufferedImage expectedImage, BufferedImage actualImage, Rectangle rectangle, Offset offset) { CalcSimilarityPrep prep = prepareCalcSimilarity(expectedImage, actualImage, rectangle, offset); int r, g, b, bestX = 0, bestY = 0; int thresDiffCount, thresDiffMin = -1; int totalDiffCount, totalDiffMin = -1; double similarityThresDiff, similarityTotalDiff; double norm = 0, min = -1; double diffThreshold = ComparisonParameterDefaults.getDiffThreshold(); 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++) { thresDiffCount = 0; totalDiffCount = 0; norm = 0; for (int i = 0; i < prep.actualHeight; i++) { for (int j = 0; j < prep.actualWidth; j++) { r = prep.expectedRed[prep.expectedWidth * (i + y) + (j + x)] - prep.actualRed[prep.actualWidth * i + j]; g = prep.expectedGreen[prep.expectedWidth * (i + y) + (j + x)] - prep.actualGreen[prep.actualWidth * i + j]; b = prep.expectedBlue[prep.expectedWidth * (i + y) + (j + x)] - prep.actualBlue[prep.actualWidth * i + j]; norm += Math.sqrt(r * r + g * g + b * b); if (r * r + g * g + b * b > 3 * 255 * 255 * diffThreshold * diffThreshold) thresDiffCount++; if (r * r + g * g + b * b > 0) totalDiffCount++; } } if (norm < min || min == -1) { min = norm; bestX = prep.leftMove - x; bestY = prep.topMove - y; } if (totalDiffCount < totalDiffMin || totalDiffMin == -1) { totalDiffMin = totalDiffCount; } if (thresDiffCount < thresDiffMin || thresDiffMin == -1) { thresDiffMin = thresDiffCount; } } } double similarity; similarity = 1 - min / (Math.sqrt(3) * 255 * prep.actualWidth * prep.actualHeight); similarityThresDiff = 1 - (double) thresDiffMin / (prep.actualWidth * prep.actualHeight); similarityTotalDiff = 1 - (double) totalDiffMin / (prep.actualWidth * prep.actualHeight); similarity = Math.floor(similarity * 100) / 100; similarityThresDiff = Math.floor(similarityThresDiff * 100) / 100; similarityTotalDiff = Math.floor(similarityTotalDiff * 100) / 100; if (offset == null) { offset = new Offset(0, 0); } if (prep.maxMove != 0) { offset.setX(bestX); offset.setY(bestY); } return new SimilarityUnit(offset.getX(), offset.getY(), similarity, 0, similarityThresDiff, similarityTotalDiff); } 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 testCalcSimilarityPixelByPixel() 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); SimilarityUnit calcSimilarityPixelByPixel = SimilarityUtils.calcSimilarityPixelByPixel(image1, image2, rectangle, offset); double actual = calcSimilarityPixelByPixel.getSimilarityPixelByPixel(); assertThat(actual, is(1.0)); }
@Test public void testCalcSimilarityPixelByPixelWithDiff() 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); SimilarityUnit calcSimilarityPixelByPixel = SimilarityUtils.calcSimilarityPixelByPixel(image1, image2, rectangle, offset); double actual = calcSimilarityPixelByPixel.getSimilarityPixelByPixel(); assertThat(actual, is(0.99)); }