%--------------------------------------------------
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);