Homework 5: 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? (yes-sympad. thanks Lexing. but since
% this works already, it's easier to leave it... :)
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));
Sobel.m
function [gm,em] = sobel(im, T)
% [GM,EM] = SOBEL(IMG,T)
% Apply the Sobel gradient operator.
% GM is the gradient magnitude
% EM is the edge map based on threshold T (T in range (0,1))
% The actual threshold value is determined such that 100*T% of pixels in gradient
% are kept as edges (T defaults to .10).
if nargin<2
T = .10;
end
H1 = [-1 0 1
-2 0 2
-1 0 1];
H2 = H1';
[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? (yes-sympad. thanks Lexing. but since
% this works already, it's easier to leave it... :)
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
% Apply horizontal gradient
g1 = zeros(padR,padC);
for i = (offset+1):(offset+R)
for j = (offset+1):(offset+C)
g1(i,j) = paddedImg(i,j) - sum(sum(H1 .* paddedImg((i-padTL):(i+padBR),(j-padTL):(j+padBR))));
end
end
% Apply vertical gradient
g2 = zeros(padR,padC);
for i = (offset+1):(offset+R)
for j = (offset+1):(offset+C)
g1(i,j) = sum(sum(H2 .* paddedImg((i-padTL):(i+padBR),(j-padTL):(j+padBR))));
end
end
% gradient magnitude:
gm = sqrt(g1.^2 + g2.^2);
% discard padded extensions
gm = gm((offset+1):(offset+R),(offset+1):(offset+C));
% normalize back to [0,1]
%gm = gm ./ max(max(gm));
% threshold to get the edge map
THRESH_PERCENT = 1-T; % so 100*T% of pixels will be kept
NBINS = 1000;
% define threshold dynamically so that there are THRESH_PERCENT pixels in the edge map
[h,bins] = hist(gm(:),NBINS);
ch = cumsum(h);
% threshold cum pdf
ch = find(ch > THRESH_PERCENT * sum(h));
t = bins(ch(1));
em = (gm > t);
edgemap.m
function em = edgemap(g,T)
% EM= EDGEMAP(G,T)
% threshold the gradient G at 100*T% to get the edge map EM
% Adam Berenzweig, April 2001
% threshold to get the edge map
THRESH_PERCENT = 1-T; % so 100*T% of pixels will be kept
NBINS = 1000;
% define threshold dynamically so that there are THRESH_PERCENT of pixels in the edge map
[h,bins] = hist(g(:),NBINS); % abs cuz laplacian gives neg and pos values
ch = cumsum(h);
% threshold cum pdf
ch = find(ch > THRESH_PERCENT * sum(h));
t = bins(ch(1));
em = (g > t);
laplace.m
function [g,em] = laplace(im,T,op)
% [L,EM] = LAPLACE(IMG,T,OP)
% Apply the Laplacian gradient operator.
% L is the Laplacian gradient
% EM is the edge map based on threshold T (T in range (0,1))
% The actual threshold value is determined such that 100*T% of pixels in gradient
% are kept as edges (T defaults to .10).
% OP is which discrete laplacian to use: (default is L2):
% L1 = [ 0 -1 0
% -1 4 -1
% 0 -1 0 ];
%
% L2 = [ -1 -1 -1
% -1 8 -1
% -1 -1 -1 ];
%
% L3 = [ 1 -2 1
% -2 4 -2
% 1 -2 1 ];
if nargin<2
T = .10;
end
L1 = [ 0 -1 0
-1 4 -1
0 -1 0 ];
L2 = [ -1 -1 -1
-1 8 -1
-1 -1 -1 ];
L3 = [ 1 -2 1
-2 4 -2
1 -2 1 ];
% choose which laplacian from table 4:
if nargin < 3
L = L2;
else
Ls = {L1 L2 L3};
L = Ls{op};
end
L
[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? (yes-sympad. thanks Lexing. but since
% this works already, it's easier to leave it... :)
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
% Apply laplacian
g = zeros(padR,padC);
for i = (offset+1):(offset+R)
for j = (offset+1):(offset+C)
g(i,j) = sum(sum(L .* paddedImg((i-padTL):(i+padBR),(j-padTL):(j+padBR))));
end
end
% discard padded extensions
g = g((offset+1):(offset+R),(offset+1):(offset+C));
% normalize back to [0,1]
%g = g ./ max(max(g));
% threshold to get the edge map
THRESH_PERCENT = 1-T; % so 100*T% of pixels will be kept
NBINS = 1000;
% de-mean to center the histogram
g = g - mean(g(:));
% define threshold dynamically so that there are THRESH_PERCENT pixels in the edge map
[h,bins] = hist(abs(g(:)),NBINS); % abs cuz laplacian gives neg and pos values
ch = cumsum(h);
% threshold cum pdf
ch = find(ch > THRESH_PERCENT * sum(h));
t = bins(ch(1));
em = (abs(g) > t);
dbledgemap.m
function em = dbledgemap(g,T)
% EM= DBLEDGEMAP(G,T)
% threshold the (laplacian) gradient G at 100*T% to get the
% (double) edge map EM
% Adam Berenzweig, April 2001
% threshold to get the edge map
THRESH_PERCENT = 1-T; % so 100*T% of pixels will be kept
NBINS = 1000;
% de-mean to center the histogram
%g = g - mean(g(:));
% define threshold dynamically so that there are THRESH_PERCENT of pixels in the edge map
[h,bins] = hist(abs(g(:)),NBINS); % abs cuz laplacian gives neg and pos values
ch = cumsum(h);
% threshold cum pdf
ch = find(ch > THRESH_PERCENT * sum(h));
t = bins(ch(1));
em = (abs(g) > t);
Back