function out = medianFilt(in, width)
% out = medianFilt(in, width)
%
% 2-D median filter designed for use with odd window width.
% Written by Matt Golub for Psych 221, Winter Quarter, 2008.
%
% INTPUTS: in - A 2-D orientation map produced by orientationMatrix.m.
%          width - The median filter width, should be odd.
% OUTPUTS: out - The resulting median-filtered orientation matrix.

if mod(width,2)==0
    error('Use an odd window width.');
end

padLen = floor(width/2);

topLeftSquare = ones(padLen,padLen)*in(1,1);
topRightSquare = ones(padLen,padLen)*in(1,end);
bottomLeftSquare = ones(padLen,padLen)*in(end,1);
bottomRightSquare = ones(padLen,padLen)*in(end,end);

leftPad = in(:,1);
rightPad = in(:,end);
topPad = in(1,:);
bottomPad = in(end,:);

n=1;
while n<padLen,
    leftPad = [leftPad(:,1) leftPad];
    rightPad = [rightPad(:,1) rightPad];
    topPad = [topPad(1,:); topPad];
    bottomPad = [bottomPad(1,:); bottomPad];
    n=n+1;
end;

topSection = [topLeftSquare topPad topRightSquare];
bottomSection = [bottomLeftSquare bottomPad bottomRightSquare];
midSection = [leftPad in rightPad];

padMat = [topSection; midSection; bottomSection];

[rows, cols]=size(in);
for(n=1:rows)
    for(m=1:cols)
        block=padMat(n:n+width-1,m:m+width-1);
        out(n,m) = median(median((block)));
    end
    if (mod(n,round(rows/50))==1)
        disp(['Median filtering ' num2str(round(100*n/rows)) '% complete.']);
    end
end        