/****************************************************************************** * Compilation: javac -classpath .:jama.jar KarhunenLoeve.java * Execution: java -classpath .:jama.jar KarhunenLoeve M N * Dependencies: jama.jar * * Compute best rank r approximation to matrix using SVD. * * http://math.nist.gov/javanumerics/jama/ * http://math.nist.gov/javanumerics/jama/Jama-1.0.1.jar * ******************************************************************************/ import Jama.Matrix; import Jama.SingularValueDecomposition; import java.awt.Color; public class KarhunenLoeve { // return the integer between 0 and 255 closest to c public static int truncate(double c) { if (c <= 0) return 0; if (c >= 255) return 255; return (int) (c + 0.5); } public static Matrix KL(Matrix A, int r) { int m = A.getRowDimension(); int n = A.getColumnDimension(); SingularValueDecomposition svd = A.svd(); Matrix Ur = svd.getU().getMatrix(0, m-1, 0, r-1); // first r columns of U Matrix Vr = svd.getV().getMatrix(0, n-1, 0, r-1); // first r columns of V Matrix Sr = svd.getS().getMatrix(0, r-1, 0, r-1); // first r rows and columns of S return Ur.times(Sr).times(Vr.transpose()); } public static void main(String[] args) { // rank of approximation int rank = Integer.parseInt(args[1]); // read in the original picture and display it Picture pic1 = new Picture(args[0]); int m = pic1.height(); int n = pic1.width(); pic1.show(); System.err.println("Done reading " + m + "-by-" + n + " image"); // create matrix of grayscale intensities Matrix A = new Matrix(m, n); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { Color color = pic1.get(i, j); double luminance = Luminance.intensity(color); A.set(i, j, luminance); } } // compute best approximation of given rank Matrix Ar = KL(A, rank); System.err.println("Done computing best rank " + rank + " approximation"); // create new picture Picture pic2 = new Picture(m, n); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { int y = (int) (Math.round(truncate(Ar.get(i, j)))); Color gray = new Color(y, y, y); pic2.set(i, j, gray); } } pic2.show(); System.err.println("Done"); } }