function MakeMosaic(imgName, direcIn, smallSize, cost) % % MakeMosaic(imgName, direcIn, smallSize, cost) % % This function uses the images in 'direcIn' and tries to make a mosaic % version of imgName using them (imgName is the filename of an image % file). It shrinks the images in direcIn down to smallSize (say, [30 % by 30]) before making the mosaic of them, and uses the number in cost % to penalize images repeating (larger cost == less repeats). On subsequent % mosaics with the same image directory (direcIn), it runs very quickly % since it caches the image's color information and keeps the small images % around. % % Timothy F. Brady, tfbrady@mit.edu, Sept. 2008 % img = imread(imgName); fprintf('Making small images\n'); direcOut = [direcIn 'Small']; MakeSmall(direcIn, direcOut, smallSize); fprintf(' -> Made small images\n\n'); fprintf('Making color summary\n'); colorsMat = SummaryColors(direcOut); fprintf(' -> Saved color summary\n\n'); fprintf('Making best fits\n'); newBest = BestFit(img, colorsMat, cost); save bestFits.mat newBest; fprintf(' -> Made best fits\n\n'); fprintf('Making mosaic\n'); mosaicImage = MakeMosaicFinal(direcOut, newBest, img, smallSize); fprintf('\nWriting out mosaic\n'); imwrite(mosaicImage, 'mosaic.jpg'); %-------------------------------------------------------------------------- function mosaicImage = MakeMosaicFinal(imgSrc, newBest, img, smallSize) % combine images into one big one lst = dir(imgSrc); mosaicImage = zeros(size(img,1)*smallSize(1), ... size(img,2)*smallSize(2), ... 3); for i=1:size(newBest,1) for j=1:size(newBest,2) imgT = imread(fullfile(imgSrc, lst(newBest(i,j)).name)); mosaicImage((i-1)*smallSize(1) + 1 : i*smallSize(1), ... (j-1)*smallSize(2) + 1 : j*smallSize(2), ... 1:3) = ... double(imgT(1:smallSize(1), 1:smallSize(2), 1:3)) ./ 255; end if mod(i,10)==0, fprintf(' - Row %d\n', i); end end %-------------------------------------------------------------------------- function newBest = BestFit(img, colorsMat, costPerUse) % Min error fit of colors to pixels newBest = zeros(size(img,1), size(img,2)); costFunc = zeros(size(colorsMat,1), 1); randOrder = fullfact([size(img,1) size(img,2)]); whichR = Shuffle(1:size(randOrder)); randOrderI = Shuffle(1:size(img,1)); randOrderJ = Shuffle(1:size(img,2)); for iW=1:length(whichR) cur = whichR(iW); i = randOrder(cur,1); j = randOrder(cur,2); curColor = squeeze(img(i,j,:))'; curColorRep = repmat(curColor, [size(colorsMat,1) 1]); errMat = double(curColorRep) - colorsMat; errMat = sum(errMat .* errMat,2) + costFunc; [v, bestImg] = min(errMat); newBest(i,j) = bestImg; costFunc(bestImg) = costFunc(bestImg) + costPerUse; end %-------------------------------------------------------------------------- function colorsMat = SummaryColors(direcIn) % Make small versions of everything in a directory if ~exist('colsList.mat') lst = dir(direcIn); for i=1:length(lst) colorsList{i,1} = [Inf Inf Inf]; try imgT = imread(fullfile(direcIn, lst(i).name)); colorsList{i,1} = squeeze(mean(mean(imgT,1),2))'; end end colorsMat = cell2mat(colorsList); save('colsList.mat','colorsList','colorsMat'); else load('colsList.mat'); end %-------------------------------------------------------------------------- function MakeSmall(direcIn, direcOut, sizeNew) % Make small versions of everything in a directory if ~exist(direcOut) mkdir(direcOut); lst = dir(direcIn); for i=3:length(lst) try imgT = imread(fullfile(direcIn, lst(i).name)); imgT = imresize(imgT, sizeNew); imwrite(imgT, fullfile(direcOut, lst(i).name)); end end end