package edu.stanford.rsl.tutorial.modelObserver; import edu.stanford.rsl.conrad.data.numeric.Grid2D; import edu.stanford.rsl.conrad.numerics.SimpleMatrix; import edu.stanford.rsl.conrad.numerics.SimpleOperators; import edu.stanford.rsl.conrad.numerics.SimpleVector; import edu.stanford.rsl.conrad.numerics.SimpleMatrix.InversionType; /** * @author Iris Kellermann */ public class Observer { /** * Calculates the difference of the mean images of the given image arrays. * @param objectImages The array of images with present object. * @param emptyImages The array of empty images. * @return The mean difference image. */ public static SimpleMatrix GetMeanDifferenceImage(SimpleMatrix[] objectImages, SimpleMatrix[] emptyImages) { try { SimpleMatrix meanObjectImage = ImageHelper.GetMeanImage(objectImages); SimpleMatrix meanEmptyImage = ImageHelper.GetMeanImage(emptyImages); meanObjectImage.subtract(meanEmptyImage); return meanObjectImage; } catch(Exception e) { System.out.println(e.getMessage()); } return null; } /** * Calculates the mean covariance matrix of channelized image arrays. * @param objectImages The array of images with present object. * @param emptyImages The array of empty images. * @param channelMatrix The matrix containing the channel image vectors. * @return The result matrix. */ public static SimpleMatrix GetCovarianceMatrix(SimpleMatrix[] objectImages, SimpleMatrix[] emptyImages, SimpleMatrix channelMatrix) { SimpleMatrix meanObjectImage = ImageHelper.GetMeanImage(objectImages); SimpleMatrix meanEmptyImage = ImageHelper.GetMeanImage(emptyImages); SimpleMatrix[] MeanCovariance = new SimpleMatrix[2]; MeanCovariance[0] = new SimpleMatrix (channelMatrix.getCols(), channelMatrix.getCols()); MeanCovariance[1] = new SimpleMatrix (channelMatrix.getCols(), channelMatrix.getCols()); for(int i = 0; i < objectImages.length; ++i) { SimpleVector differenceImage = ImageHelper.ConvertSimpleMatrixToVector(SimpleOperators.subtract(objectImages[i], meanObjectImage)); SimpleVector channelizedImage = SimpleOperators.multiply(channelMatrix.transposed(), differenceImage); MeanCovariance[0].add(SimpleOperators.multiplyOuterProd(channelizedImage, channelizedImage)); } MeanCovariance[0].divideBy(objectImages.length); for(int i = 0; i < emptyImages.length; ++i) { SimpleVector differenceImage = ImageHelper.ConvertSimpleMatrixToVector(SimpleOperators.subtract(emptyImages[i], meanEmptyImage)); SimpleVector channelizedImage = SimpleOperators.multiply(channelMatrix.transposed(), differenceImage); MeanCovariance[1].add(SimpleOperators.multiplyOuterProd(channelizedImage, channelizedImage)); } MeanCovariance[1].divideBy(emptyImages.length); //mean of covariance matrixes return ImageHelper.GetMeanImage(MeanCovariance); } /** * Creates the template for the observer. * @param testModels The array of images with present object. * @param emptyImages The array of empty images. * @param channelMatrix The matrix containing the channel image vectors. * @return The result value. */ public static SimpleVector CreateTemplate(Grid2D[] testModels, Grid2D[] emptyImages, SimpleMatrix channelMatrix) { //convert Grid2D images to SimpleMatrix SimpleMatrix[] objectImagesMatrix = new SimpleMatrix[testModels.length]; SimpleMatrix[] emptyImagesMatrix = new SimpleMatrix[emptyImages.length]; for(int i = 0; i < testModels.length; ++i) { objectImagesMatrix[i] = ImageHelper.ConvertGrid2DToSimpleMatrix(testModels[i]); } for(int i = 0; i < emptyImages.length; ++i) { emptyImagesMatrix[i] = ImageHelper.ConvertGrid2DToSimpleMatrix(emptyImages[i]); } SimpleMatrix meanDifferenceImage = Observer.GetMeanDifferenceImage(objectImagesMatrix, emptyImagesMatrix); SimpleMatrix covarianceMatrix = Observer.GetCovarianceMatrix(objectImagesMatrix, emptyImagesMatrix, channelMatrix); //convert meanDifferenceImage to columns SimpleVector meanDifferenceVector = ImageHelper.ConvertSimpleMatrixToVector(meanDifferenceImage); //calculate channelized mean-difference image s_v SimpleVector s_v = SimpleOperators.multiply(channelMatrix.transposed(), meanDifferenceVector); //create template SimpleMatrix C_vInverted = covarianceMatrix.inverse(InversionType.INVERT_QR); SimpleVector templateVector = SimpleOperators.multiply(s_v, C_vInverted); return templateVector; } /** * Calculates the result of the observer. * @param model The test model. * @param template The template of the observer. * @param channelMatrix The matrix containing the channel image vectors. * @return The result value. */ public static double GetResultValue(Grid2D model, SimpleVector template, SimpleMatrix channelMatrix) { //convert Grid2D images to SimpleMatrix SimpleVector modelVector = ImageHelper.ConvertSimpleMatrixToVector(ImageHelper.ConvertGrid2DToSimpleMatrix(model)); //the channelized model image SimpleVector vVector = SimpleOperators.multiply(channelMatrix.transposed(), modelVector); double resultValue = SimpleOperators.multiplyInnerProd(template, vVector); return resultValue; } } /* * Copyright (C) 2010-2014 - Iris Kellermann * CONRAD is developed as an Open Source project under the GNU General Public License (GPL). */