% Two arguments: The filename to save image as. And the quality 1-64. Where % 64 is best, but also unnecssary since no compression will occur. % Author: Magnus Lundstedt, 810109-8617 function [uncomp,raw,avg,base]=compress (filename,quality) load lena; M = extract(lena); %--- Find average image element avgImg = zeros(64,1); for i = 1:1024 avgImg = avgImg + 1/1024 * M(:,[i]); end %--- Translate all elements by average element translated = zeros(64,1024); for i = 1:1024 translated(:,[i]) = M(:,[i])-avgImg; end %--- Find covariance-matrix on transponate of translated matrix C = cov(translated'); %--- Calculate eigenvalues and eigenvectors of the covariance matrix [eigvect,eigval] = eig(C); %--- Select 10 biggest eigenvalues and their corresponding eigenvectors %these eigenvectors will be our new base intrVal = eigval([65-quality:64],[1]); intrVect = eigvect(:,[65-quality:64]); %intrVect = eigvect(:,[1:quality]); %--- Change base-loop for i = 1:1024 %--- Compressed data in our new base raw(:,[i]) = intrVect' * translated(:,[i]); %--- At the same time reconstruct the image so that we dont have to % do a separate decoder :) newSubImages(:,[i]) = intrVect*raw(:,[i])+avgImg; end %Find a suitable factor to maximize useage of the 256 possible states %when we convert the double into an signed int later.. (Here one could %prioritize some colors where humans notice difference more eaisily) factor = 128/max(max(abs(raw))); uncomp = newSubImages; avg = avgImg; raw = int8(round(raw*factor)); base = int8(round(intrVect*factor)); save(filename,'raw','avg','base','factor'); end