%--------------------------------------------------
function [smoothed] = medfilter(image, fsize)
size=length(image);
start=round(fsize/2);
int=start-1;
for j=start:size-start,
for i=start:size-start,
smoothed(j-start+1,i-start+1)=median(median(image(j-int:j+int,i-int:i
+int)));
end
end
%--------------------------------------------------
% this function performs edge detection on the smoothed image and counts up
% the coins in the imgae.
function [count, qtest, ptest, ntest, pnum, nnum, dnum, qnum]=coincount(orig, smooth)
% edge detection using the gradient methods
A=edge(smooth,'roberts');
figure(2);
colormap(gray(256));
imagesc(A);
title('edges');
axis('square');
% we only do square matrices
count=0; % cumulative sum
size=length(A);
thres=8; % as long as we get 8 hits, we count it as a coin
% radii for the four different sizes of coins
radius_q = 38;
radius_p = 29;
radius_n = 34;
dnum =0;
nnum=0;
pnum=0;
qnum=0;
qtest=[];
ptest=[];
ntest=[];
for i=1:size,
for j=1:size,
%*******************************************
% see if this pixel is a center of quarter
hits_q=center(A,i,j,radius_q);
qtest(i,j)=hits_q;
if (hits_q >= 5)
hits_q=hits_q+checkmore(A,i,j,radius_q);
qtest(i,j)=hits_q;
end
%*******************************************
% see if this pixel is a center of penny/dime
hits_p=center(A,i,j,radius_p);
ptest(i,j)=hits_p;
if (hits_p >= 5)
hits_p=hits_p+checkmore(A,i,j,radius_p);
ptest(i,j)=hits_p;
end
%*******************************************
% see if this pixel is a center of nickel
hits_n=center(A,i,j,radius_n);
ntest(i,j)=hits_n;
if (hits_n >= 5)
hits_n=hits_n+checkmore(A,i,j,radius_n);
ntest(i,j)=hits_n;
end
end
end
for i=1:size,
for j=1:size,
if (qtest(i,j) >= thres & checkaround(qtest,i,j,thres)==1)
count = count+0.25;
qnum=qnum+1;
end
if (ptest(i,j) >= thres & checkaround(ptest,i,j,thres)==1)
% check the brightness of coin
if (orig(i,j) > 200)
count = count+0.1;
dnum = dnum+1;
else
count = count+0.01;
pnum = pnum + 1;
end
end
if (ntest(i,j) >= thres & checkaround(ntest,i,j,thres)==1)
count = count+0.05;
nnum = nnum + 1;
end
end
end
%--------------------------------------------------
function [hits] = center(A,i,j,radius)
% input arguments: A = image of edges
% i,j = position under test
% radius = which coin to look for?
num = 0;
size=length(A);
range1=1;
range2=1;
% check up
if ((i>radius+range1) & (max(A(i-radius-range1:i-radius+range2,j)==1)==1))
num=num+1;
end
% check down
if ((i<=size-radius-range2) & (max(A(i+radius-range1:i+radius+range2,j)==1)==1))
num=num+1;
end
% check left
if ((j>radius+range1) & (max(A(i,j-radius-range1:j-radius+range2)==1)==1))
num=num+1;
end
% check right
if ((j<=size-radius-range2) & (max(A(i,j+radius-range1:j+radius+range2)==1)==1))
num=num+1;
end
% if no hits yet, then we can give up!
if (num ~= 0)
diag = round(radius/sqrt(2));
% check NE
if ((i>diag+range1) & (j<=size-diag-range1) & (max(A(i-diag-range1:i-diag+range1,j+diag+range1:-1:j+diag-range1)==1)==1))
num=num+1;
end
% check SE
if ((i<=size-diag-range1) & (j<=size-diag-range1) & (max(A(i+diag-range1:i+diag+range1,j+diag-range1:j+diag+range1)==1)==1))
num=num+1;
end
% check NW
if ((i>diag+range1) & (j>diag+range1) & (max(A(i-diag-range1:i-diag+range1,j-diag-range1:j-diag+range1)==1)==1))
num=num+1;
end
% check SW
if ((i<=size-diag-range1) & (j>diag+range1) & (max(A(i+diag-range1:i+diag+range1,j-diag+range1:-1:j-diag-range1)==1)==1))
num=num+1;
end
end
hits = num;
%--------------------------------------------------
function [hits] = checkmore(A,i,j,radius)
% input arguments: A = image of edges
% i,j = position under test
% radius = which coin to look for?
num = 0;
size=length(A);
range1=1;
% check the 30 degrees
y = round(radius/2);
x = round(radius*sqrt(3)/2);
% check NE
if ((i>x+range1) & (j<=size-y-range1) & (max(A(i-x-range1:i-x+range1,j+y+range1:-1:j+y-range1)==1)==1))
num=num+1;
end
% check SE
if ((i<=size-x-range1) & (j<=size-y-range1) & (max(A(i+x-range1:i+x+range1,j+y-range1:j+y+range1)==1)==1))
num=num+1;
end
% check NW
if ((i>x+range1) & (j>y+range1) & (max(A(i-x-range1:i-x+range1,j-y-range1:j-y+range1)==1)==1))
num=num+1;
end
% check SW
if ((i<=size-x-range1) & (j>y+range1) & (max(A(i+x-range1:i+x+range1,j-y+range1:-1:j-y-range1)==1)==1))
num=num+1;
end
% check the 60 degrees
x = round(radius/2);
y = round(radius*sqrt(3)/2);
% check NE
if ((i>x+range1) & (j<=size-y-range1) & (max(A(i-x-range1:i-x+range1,j+y+range1:-1:j+y-range1)==1)==1))
num=num+1;
end
% check SE
if ((i<=size-x-range1) & (j<=size-y-range1) & (max(A(i+x-range1:i+x+range1,j+y-range1:j+y+range1)==1)==1))
num=num+1;
end
% check NW
if ((i>x+range1) & (j>y+range1) & (max(A(i-x-range1:i-x+range1,j-y-range1:j-y+range1)==1)==1))
num=num+1;
end
% check SW
if ((i<=size-x-range1) & (j>y+range1) & (max(A(i+x-range1:i+x+range1,j-y+range1:-1:j-y-range1)==1)==1))
num=num+1;
end
hits = num;
%--------------------------------------------------
function [bool]=checkaround(A,i,j,th)
if ( (max(max(A(i-4:i-1,j-4:j+4) >= th)) == 1) | (max(A(i, j-4:j-1) >= th) == 1))
bool=0;
else
bool=1;
end;
%--------------------------------------------------
function [r,edge1, edge2] = radius(coin)
% coin is _edge-detected_ square image of original coin
edge1 = 0;
edge2 = 0;
edgei = -1;
edgej = -1;
[row,col] = size(coin);
for j = 1:col,
for i = 1:row,
if coin(i,j) == 1,
edgei = i;
edgej = j;
break;
end
end
if edgei ~= -1,
break;
end
end
while coin(edgei,edgej) == 1,
edgej = edgej+1;
end
% edge1 is the inner left-most edge
edge1 = edgej - 1;
for j = (edgej):col,
coin(edgei,j)
if coin(edgei,j) == 1,
% edge2 is the inner-most right edge
edge2 = j;
break;
end
end
r = round((edge2-edge1)/2);
%--------------------------------------------------
function [r,edge1, edge2] = radius(coin)
% coin is _edge-detected_ square image of original coin
edge1 = 0;
edge2 = 0;
edgei = -1;
edgej = -1;
[row,col] = size(coin);
for i = 1:row,
for j = 1:col,
if coin(i,j) ==1,
edgei = i;
edgej = j;
break;
end
end
if edgej ~= -1,
break;
end
end
while coin(edgei,edgej) ==1,
edgei = edgei+1;
end
% edge1 is the inner top-most edge
edge1 = edgei - 1;
edgei = edgei+5;
for i = (edgei):row,
coin(i,edgej)
if coin(i,edgej) ==1,
% edge2 is the inner-most right edge
edge2 = i;
break;
end
end;
r = round((edge2-edge1)/2);