Mercurial > hg > ThermostatQA
changeset 103:befe5e58f30f
Refactoring, added and improved JavaDoc, fix some minor issues.
author | Pavel Tisnovsky <ptisnovs@redhat.com> |
---|---|
date | Tue, 01 Oct 2013 09:35:08 +0200 |
parents | 18a11b9d62ea |
children | 3100f7de547b |
files | ChangeLog src/org/thermostat/qa/framework/ImageProcessing.java test.properties |
diffstat | 3 files changed, 95 insertions(+), 45 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Mon Sep 30 10:22:07 2013 +0200 +++ b/ChangeLog Tue Oct 01 09:35:08 2013 +0200 @@ -1,3 +1,8 @@ +2013-10-01 Pavel Tisnovsky <ptisnovs@redhat.com> + + * src/org/thermostat/qa/framework/ImageProcessing.java: + Refactoring, added and improved JavaDoc, fix some minor issues. + 2013-09-30 Pavel Tisnovsky <ptisnovs@redhat.com> * src/org/thermostat/qa/framework/ThermostatTest.java:
--- a/src/org/thermostat/qa/framework/ImageProcessing.java Mon Sep 30 10:22:07 2013 +0200 +++ b/src/org/thermostat/qa/framework/ImageProcessing.java Tue Oct 01 09:35:08 2013 +0200 @@ -35,6 +35,14 @@ import java.awt.Rectangle; import java.awt.image.BufferedImage; + + +/** + * This class contains methods for checking if some input image contains given + * pattern. Current algorithm can be used for sRGB images. + * + * @author Pavel Tisnovsky + */ public class ImageProcessing { /** @@ -45,24 +53,28 @@ /** * Create three-dimensional array with the same size as tested image - * dimensions (last dimension is used for storing RGB components). + * dimensions (the last dimension is used for storing RGB components). * * @param testImage * tested image * @return newly created two-dimensional array */ - private static float[][][] createArrayForOneColorComponent(BufferedImage testImage) + private static float[][][] createArrayForAllColorComponents(BufferedImage testImage) { return new float[testImage.getHeight()][testImage.getWidth()][3]; } /** - * Conversion from BufferedImage into three dimensional float arrays. - * It's much faster to work with float arrays even if it's memory inefficient. - * + * Perform conversion from BufferedImage into three dimensional float + * arrays. It's much faster to work with float arrays on current CPUs even + * if it's memory inefficient. Pixels in the float array are stored with + * offset=average_value. This means, that value of color components might + * be negative. + * * @param testImage * tested image - * @param array array to fill + * @param array + * array to fill */ private static void convertImageToFloatArray(BufferedImage testImage, float[][][] array) { @@ -73,6 +85,7 @@ { for (int x = 0; x < testImage.getWidth(); x++) { + // get the RGBA values packed in one integer int c = testImage.getRGB(x, y); // filter out alpha channel c = c & 0xffffff; @@ -93,6 +106,7 @@ { for (int x = 0; x < testImage.getWidth(); x++) { + // get the RGBA values packed in one integer int c = testImage.getRGB(x, y); // filter out alpha channel c = c & 0xffffff; @@ -103,57 +117,83 @@ } } - public static Rectangle findPattern(BufferedImage marker, BufferedImage screen){ - Rectangle actionArea = new Rectangle(0,0,screen.getWidth(),screen.getHeight()); - Rectangle result = new Rectangle(0,0,0,0); + /** + * Tries to find given pattern in an input image. Only the exact pattern + * could be found by this method. + * + * @param pattern + * given pattern stored represented as BufferedImage + * @param inputImage + * input image + * @return rectangle containing area where the pattern has been found, or + * null + */ + public static Rectangle findPattern(BufferedImage pattern, BufferedImage inputImage){ + Rectangle actionArea = new Rectangle(0, 0, inputImage.getWidth(), inputImage.getHeight()); + Rectangle result = new Rectangle(0, 0, 0, 0); boolean found = false; boolean ok = true; - - for(int x = actionArea.x; (x < (actionArea.x + actionArea.width - marker.getWidth()) ) && !found; x++){ - for(int y= actionArea.y; (y < (actionArea.y + actionArea.height - marker.getHeight()) ) && !found; y++){ - - for(int mx = 0; (mx < marker.getWidth()) && ok; mx++){ - for(int my = 0; (my < marker.getHeight()) && ok; my++){ - if(marker.getRGB(mx, my) != screen.getRGB(x+mx,y+my)){ + + PATTERN_FOUND: + for (int x = actionArea.x; (x < (actionArea.x + actionArea.width - pattern.getWidth())) && !found; x++) + { + for (int y = actionArea.y; (y < (actionArea.y + actionArea.height - pattern.getHeight())) && !found; y++) + { + for (int mx = 0; (mx < pattern.getWidth()) && ok; mx++) + { + for (int my = 0; (my < pattern.getHeight()) && ok; my++) + { + if (pattern.getRGB(mx, my) != inputImage.getRGB(x + mx, y + my)) + { ok = false; } } } - if( ok ){ + if (ok) + { found = true; result.x = x; result.y = y; - result.height = marker.getHeight(); - result.width = marker.getWidth(); - }else{ - ok = true; - } + result.height = pattern.getHeight(); + result.width = pattern.getWidth(); + break PATTERN_FOUND; + } + ok = true; } } - - if(found){ - return result; - }else{ - return null; - } + + // if the pattern has not been found, return null instead of the proper rectangle + return found ? result : null; } - private static Rectangle findBlurredPattern(BufferedImage marker, BufferedImage testImage) + /** + * Tries to find given pattern in an input image. + * + * @param pattern + * given pattern stored represented as BufferedImage + * @param inputImage + * input image + * @return rectangle containing area where the pattern have been found, or + * null + */ + protected static Rectangle findBlurredPattern(BufferedImage pattern, BufferedImage inputImage) { - int maxX = testImage.getWidth() - marker.getWidth() - 1; - int maxY = testImage.getHeight() - marker.getHeight() - 1; - int markerMaxX = marker.getWidth(); - int markerMaxY = marker.getHeight(); + int maxX = inputImage.getWidth() - pattern.getWidth() - 1; + int maxY = inputImage.getHeight() - pattern.getHeight() - 1; + int markerMaxX = pattern.getWidth(); + int markerMaxY = pattern.getHeight(); // it is much faster to work directly with color components stored as float values - float[][][] testImageArray = createArrayForOneColorComponent(testImage); - float[][][] markerImageArray = createArrayForOneColorComponent(marker); + float[][][] testImageArray = createArrayForAllColorComponents(inputImage); + float[][][] markerImageArray = createArrayForAllColorComponents(pattern); //System.out.println("Starting conversion"); - convertImageToFloatArray(testImage, testImageArray); - convertImageToFloatArray(marker, markerImageArray); + convertImageToFloatArray(inputImage, testImageArray); + convertImageToFloatArray(pattern, markerImageArray); //System.out.println("Conversion done"); + // autocorellation value is needed to compute and compare correlation values + // and to find the exact pattern (if it exists in the input image) double autocorrelation = computeCorrelation(markerMaxX, markerMaxY, markerImageArray, markerImageArray, 0, 0); int bestX = -1; @@ -166,7 +206,7 @@ //System.out.println("Processing line: " + yoffset + " of " + (maxY - 1)); for (int xoffset = 0; (xoffset < maxX) && !foundExact; xoffset++) { - double correlation = computeCorrelation(markerMaxX, markerMaxY, testImageArray, markerImageArray, yoffset, xoffset); + double correlation = computeCorrelation(markerMaxX, markerMaxY, testImageArray, markerImageArray, xoffset, yoffset); if (correlation > bestCorrelation) { bestCorrelation = correlation; @@ -187,22 +227,27 @@ { return null; } - return new Rectangle(bestX, bestY, marker.getWidth(), marker.getHeight()); + // pattern has been found! + return new Rectangle(bestX, bestY, pattern.getWidth(), pattern.getHeight()); } /** - * Compute correlation for given two images and 2D offset. - * + * Compute correlation for given two images and a 2D offset. + * * @param maxX * @param maxY * @param testImageArray + * first input array * @param markerImageArray + * second input array + * @param xoffset + * horizontal part of an offset * @param yoffset - * @param xoffset - * @return + * vertical part of an offset + * @return correlation of two arrays with the given offset */ private static double computeCorrelation(int maxX, int maxY, float[][][] testImageArray, - float[][][] markerImageArray, int yoffset, int xoffset) + float[][][] markerImageArray, int xoffset, int yoffset) { double correlation = 0; for (int y = 0; y < maxY; y++)
--- a/test.properties Mon Sep 30 10:22:07 2013 +0200 +++ b/test.properties Tue Oct 01 09:35:08 2013 +0200 @@ -1,6 +1,6 @@ thermostat_executable_path=/home/jfabriko/thermostaty/testing_thermostat/thermostat/distribution/target/image/bin/ thermostat_executable_name=thermostat -thermostat_output_version=version6-0.14.0 +thermostat_output_version=0.12.0 thermostat_home=/home/jfabriko/thermostaty/testing_thermostat/thermostat/distribution/target/image/ thermostat_user_home=/home/jfabriko/.thermostat/ apache_tomcat_home=/home/jfabriko/thermostaty/apache-tomcat-7.0.42/