function database = preprocess(imagebase,param)
% This function is to normalize images following the method of Koray'CVPR09
% Input:   imagebase -- the database of original image sets
%          param -- maxImgSize and localNormRange are needed 
% Output:  database -- the database of normalized images
% Written by Jimei Yang
% Oct. 28, 2009

% default parameters follow the settings in Koray'CVPR09
if ~isfield(param,'maxImgSize')
    param.maxImgSize = 151;
end
if ~isfield(param,'localNormRange')
    param.localNormRange = 9;
end

database = imagebase;

for i = 1:imagebase.imnum
    fprintf('preprocess the image...');
    tic;
    I = imread(imagebase.path{i});
    if ndims(I) == 3
        I = im2double(rgb2gray(I));
    else
        I = im2double(I);
    end
    % resize image
    [im_h, im_w] = size(I);
    if max(im_h, im_w) > param.maxImgSize,
        I = imresize(I, param.maxImgSize/max(im_h, im_w), 'bicubic');
        [im_h, im_w] = size(I);
    end
    
    % locally normalize image
    span = (param.localNormRange-1)/2;
    img = zeros(im_h-2*span,im_w-2*span);
    imgDev = std(I(:));
    for y = 1+span:im_h-span
        for x = 1+span:im_w-span
            patch = I(y-span:y+span,x-span:x+span);
            m = mean(patch(:));
            dev = std(patch(:));
            if dev > imgDev
                img(y-span,x-span) = (I(y,x)-m)/dev;
            else
                img(y-span,x-span) = (I(y,x)-m)/imgDev;
            end
        end
    end
    [im_h,im_w] = size(img);
    if im_h < im_w
         app = round((im_w-im_h)/2);
        img = [zeros(app,im_w);img;zeros(im_w-im_h-app,im_w)];
    else
        app = round((im_h-im_w)/2);
        img = [zeros(im_h,app),img,zeros(im_h,im_h-im_w-app)];
    end
    [pdir,fname] = fileparts(imagebase.path{i});
    seps = findstr(pdir,'\');
    fdir = ['data\pp_',pdir(seps(1)+1:end)];
    if ~isdir(fdir)
        mkdir(fdir);
    end
    fpath = fullfile(fdir,[fname,'.mat']);
    save(fpath,'img');
%     figure; imshow(image,[]);
    database.path{i} = fpath;
    disp([num2str(i),' in ',num2str(toc),' seconds;']);
end