Homework 4: Matlab Code
spatavg.m
function imOut = spatavg(im, N)
% B = SPATAVG(A,N) NxN smoothing spatial average filter.
% filter coefficients
A = ones(N,N);
A = A .* (1/N);
[R,C] = size(im);
% pad near the edges with the symmetric extension
if mod(N,2)
padTL = (N-1)/2; % left and top
padBR = (N-1)/2; % bottom and right
else
padTL = N/2 - 1;
padBR = N/2;
end
offset = padTL;
paddedIm = zeros(R+N-1, C+N-1);
[padR,padC] = size(paddedIm);
% copy the main image
paddedImg((offset+1):(offset+R), (offset+1):(offset+C)) = im;
% now copy up into the symmetric extension - top, left, bottom, right
% what a pain - is there a simpler way?
paddedImg(1:padTL,(offset+1):(offset+C)) = flipud(im(1:padTL,:));
paddedImg((offset+1):(offset+R),1:padTL) = fliplr(im(:,1:padTL));
paddedImg((padR-padBR+1):padR,(offset+1):(offset+C)) = flipud(im((R-padBR+1):R,:));
paddedImg((offset+1):(offset+R),(padC-padBR+1):padC) = fliplr(im(:,(C-padBR+1):C));
% now the corners
paddedImg(1:padTL,1:padTL) = fliplr(flipud(im(1:padTL,1:padTL)));
paddedImg(1:padTL,(padC-padBR+1):padC) = fliplr(flipud(im(1:padTL,(C-padBR+1):C)));
paddedImg((padR-padBR+1):padR,(padC-padBR+1):padC) = fliplr(flipud(im((R-padBR+1):R,(C-padBR+1):C)));
paddedImg((padR-padBR+1):padR,1:padTL) = fliplr(flipud(im((R-padBR+1):R,1:padTL)));
%paddedImg % debug
% Now apply the spatial filtering
imOut = zeros(padR,padC);
for i = (offset+1):(offset+R)
for j = (offset+1):(offset+C)
imOut(i,j) = sum(sum(paddedImg((i-padTL):(i+padBR),(j-padTL):(j+padBR)) .* A));
end
end
imOut = imOut((offset+1):(offset+R),(offset+1):(offset+C));
gradientfilt.m
function imOut = gradientfilt(im)
% B = GRADIENTFILT(A) Gradient filter.
% The gradient uses the discrete laplacian;
% 1/4 * [0 1 0
% 1 0 1
% 0 1 0]
% define discrete Laplacian for gradient operation.
L = (1/4).* [0 1 0;
1 0 1;
0 1 0];
[R,C] = size(im);
N = 3;
% pad near the edges with the symmetric extension
if mod(N,2)
padTL = (N-1)/2; % left and top
padBR = (N-1)/2; % bottom and right
else
padTL = N/2 - 1;
padBR = N/2;
end
offset = padTL;
paddedIm = zeros(R+N-1, C+N-1);
[padR,padC] = size(paddedIm);
% copy the main image
paddedImg((offset+1):(offset+R), (offset+1):(offset+C)) = im;
% now copy up into the symmetric extension - top, left, bottom, right
% what a pain - is there a simpler way?
paddedImg(1:padTL,(offset+1):(offset+C)) = flipud(im(1:padTL,:));
paddedImg((offset+1):(offset+R),1:padTL) = fliplr(im(:,1:padTL));
paddedImg((padR-padBR+1):padR,(offset+1):(offset+C)) = flipud(im((R-padBR+1):R,:));
paddedImg((offset+1):(offset+R),(padC-padBR+1):padC) = fliplr(im(:,(C-padBR+1):C));
% now the corners
paddedImg(1:padTL,1:padTL) = fliplr(flipud(im(1:padTL,1:padTL)));
paddedImg(1:padTL,(padC-padBR+1):padC) = fliplr(flipud(im(1:padTL,(C-padBR+1):C)));
paddedImg((padR-padBR+1):padR,(padC-padBR+1):padC) = fliplr(flipud(im((R-padBR+1):R,(C-padBR+1):C)));
paddedImg((padR-padBR+1):padR,1:padTL) = fliplr(flipud(im((R-padBR+1):R,1:padTL)));
%paddedImg % debug
% Now apply the gradient
imOut = zeros(padR,padC);
for i = (offset+1):(offset+R)
for j = (offset+1):(offset+C)
imOut(i,j) = paddedImg(i,j) - sum(sum(L .* paddedImg((i-padTL):(i+padBR),(j-padTL):(j+padBR))));
end
end
imOut = imOut((offset+1):(offset+R),(offset+1):(offset+C));
unsharp.m
function imOut = unsharp(im, G, lambda)
% O = UNSHARP(IM,G,L) Unsharp masking
% Performs unsharp masking as follows:
% O = IM + L*G
% where G is the gradient performed by GRADIENTFILT(IM)
% O is returned normalized to (0,1)
%G = gradientfilt(im);
imOut = im + (lambda * G);
imOut = imnorm(imOut);
slice255.m
function imOut = slice255(im, a, b)
% O = SLICE(I, A, B)
% maps gray levels < A to 0, > B to 255, and preserves levels
% between A and B.
% Using 255 gray levels, so 0255 | a>b)
error('must have 0 <= A <= B <= 255');
end
mask = (im >=a & im <= b); % 1's where we want slice.
imOut= im .* mask;
imOut = imOut + ~mask;
histstretch255.m
function imOut = histstretch255(im,a,b);
% OUT = HISTSTRETCH255(IMG,A,B) Histogram stretching.
% maps the grayscale range (A,B) of the input image to
% (0,255) in the output image. values less than A are sent
% to 0, and values greater than B are sent to 255.
if (a < 0 | b>255 | a>b)
error('must have 0 <= A <= B <= 255');
end
imOut = zeros(size(im));
% first mask range < a to 0
mask = (im < a);
imOut(mask) = 0;
% now range > b to 1
mask = (im > b);
imOut(mask) = 255;
% now expand range (a,b)
mask = (im >= a & im <= b);
d = (b-a);
imOut(mask) = floor((im(mask) - a) ./ d);
medianfilt.m
function imOut = medianfilt(im, N)
% B = MEDIANFILT(A,N) NxN smoothing spatial average filter.
[R,C] = size(im);
% pad near the edges with the symmetric extension
if mod(N,2)
padTL = (N-1)/2; % left and top
padBR = (N-1)/2; % bottom and right
else
padTL = N/2 - 1;
padBR = N/2;
end
offset = padTL;
paddedIm = zeros(R+N-1, C+N-1);
[padR,padC] = size(paddedIm);
% copy the main image
paddedImg((offset+1):(offset+R), (offset+1):(offset+C)) = im;
% now copy up into the symmetric extension - top, left, bottom, right
% what a pain - is there a simpler way?
paddedImg(1:padTL,(offset+1):(offset+C)) = flipud(im(1:padTL,:));
paddedImg((offset+1):(offset+R),1:padTL) = fliplr(im(:,1:padTL));
paddedImg((padR-padBR+1):padR,(offset+1):(offset+C)) = flipud(im((R-padBR+1):R,:));
paddedImg((offset+1):(offset+R),(padC-padBR+1):padC) = fliplr(im(:,(C-padBR+1):C));
% now the corners
paddedImg(1:padTL,1:padTL) = fliplr(flipud(im(1:padTL,1:padTL)));
paddedImg(1:padTL,(padC-padBR+1):padC) = fliplr(flipud(im(1:padTL,(C-padBR+1):C)));
paddedImg((padR-padBR+1):padR,(padC-padBR+1):padC) = fliplr(flipud(im((R-padBR+1):R,(C-padBR+1):C)));
paddedImg((padR-padBR+1):padR,1:padTL) = fliplr(flipud(im((R-padBR+1):R,1:padTL)));
%paddedImg % debug
% Now apply the median filtering
imOut = zeros(padR,padC);
for i = (offset+1):(offset+R)
for j = (offset+1):(offset+C)
A = paddedImg((i-padTL):(i+padBR),(j-padTL):(j+padBR));
imOut(i,j) = median(A(:));
end
end
imOut = imOut((offset+1):(offset+R),(offset+1):(offset+C));
imnorm.m
This image normalization routine was used before writing out with imwrite.
I found that this was necessary to write .tiff images with the proper
gray values.
function imOut = imnorm(im)
% O = IMNORM(I) Image normalization
% imwrite doesnt seem to do any normalizing, so i do it here.
% normalizes to the range (0,1).
imOut = im;
% normalize
imMin = min(imOut(:));
if (imMin < 0)
imOut = imOut + abs(imMin);
end
imOut = imOut ./ max(imOut(:));
Back