/******************************************************************************* * Copyright 2006 - 2012 Vienna University of Technology, * Department of Software Technology and Interactive Systems, IFS * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package at.tuwien.minimee.migration.evaluators; import java.io.File; import java.util.ArrayList; import java.util.List; import at.tuwien.minimee.util.CommandExecutor; import at.tuwien.minimee.util.OS; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import eu.scape_project.planning.model.measurement.Measurement; import eu.scape_project.planning.model.scales.Scale; /** * This evaluator uses the ImageMagick COMPARE script to measure the difference * of two images. For this, ImageMagick must be defined properly! That means, * you need to set the IMAGEMAGICK_HOME environment variable to point to your * installation directory. * * @author cb * */ public class ImageCompareEvaluator implements IMinimeeEvaluator { private String name; private Logger log = LoggerFactory.getLogger(this.getClass()); private String compareCommand = "%IMAGEMAGICK_HOME%/compare %FILE1% %FILE2% -metric %METRIC% tempimagefile"; private String IMAGEMAGICK_HOME; /** * @throws IllegalStateException * if IMAGEMAGICK_HOME is not set */ public ImageCompareEvaluator() { IMAGEMAGICK_HOME = System.getenv("IMAGEMAGICK_HOME"); // // IMAGEMAGICK_HOME is set and the directory exists if (IMAGEMAGICK_HOME != null && new File(IMAGEMAGICK_HOME).exists()) { compareCommand = compareCommand.replace("%IMAGEMAGICK_HOME%", new File(IMAGEMAGICK_HOME).getAbsolutePath()); return; // // IMAGEMAGICK_HOME is not set, but the operating system is Linux // and the ImageMagick is installed } else if (IMAGEMAGICK_HOME == null && ("Linux".compareTo(System.getProperty("os.name")) == 0) && new File("/usr/bin/compare").exists()) { compareCommand = compareCommand.replace("%IMAGEMAGICK_HOME%", "/usr/bin"); return; } // // in all other cases, where IMAGEMAGICK_HOME is not set, we throw an // exception. if (IMAGEMAGICK_HOME == null) { throw new IllegalStateException( "ImageMagick is not propertly configured - IMAGEMAGICK_HOME is not defined."); } } public List<Measurement> evaluate(String tempDir, String file1, String file2) { List<Measurement> list = new ArrayList<Measurement>(); String[] metrics = new String[] { // see // http://www.imagemagick.org/Usage/compare/#statistics "AE", // Absolute Error count of the number of different pixels // (0=equal) "PAE", // Peak Absolute Error "PSNR", // Peak Signal to noise ratio "MAE", // Mean absolute error (average channel error distance) "MSE", // Mean squared error (averaged squared error distance) "RMSE", // (sq)root mean squared error -- IE: sqrt(MSE) "MEPP" // Normalized Mean Error AND Normalized Maximum Error }; for (String metric : metrics) { Double value = evaluate(tempDir, file1, file2, metric); list.add(new Measurement("imagequality:" + metric, value)); } return list; } public Double evaluate(String tempDir, String file1, String file2, String metric) { String commandTemplate = compareCommand.replace("%FILE1%", file1).replace("%FILE2%", file2); CommandExecutor cmdEx = new CommandExecutor(); cmdEx.setWorkingDirectory(OS.getTmpPath()); String command = commandTemplate.replace("%METRIC%", metric); try { cmdEx.runCommand(command); String out = cmdEx.getCommandError(); log.debug(command + " == " + out); Double value = Scale.MAX_VALUE; try { if (out.contains(" ")) { out = out.substring(0, out.indexOf(" ")); } value = Double.valueOf(out.trim()); } catch (NumberFormatException e) { log.error("unknown numberformat: " + out + " " + e.getMessage()); } return value; } catch (Exception e) { log.error("error during image comparison " + command + " : " + cmdEx.getCommandError(), e); return null; } } /** * unused */ public String getConfigParam() { return null; } /** * unused */ public void setConfigParam(String configParam) { } public String getName() { return name; } public void setName(String name) { this.name = name; } }