I'm trying to identify the number of matches and coins of each value in a picture using MATLAB. Here is the starting picture, with matches and 4 different coin values. (5 small silver, 2 small gold, 2 big silver, 4 big gold coins)
The output: Here's the code:
close all;
img = (imread('C:\Users\Torstein\Jottacloud\Skole\Visu\Prosjekt\sample_images\sample2.jpg'));
img_gray = rgb2gray(img);
% Filter image for easier edge detection
m = 12;
n = 12;
img_filter = imfilter(img_gray, fspecial('average', [m n]));
%figure, imshow(f), title('f')
% Edge detection
[~, threshold] = edge(img_filter, 'canny');
fudgeFactor = 1.5;
img_edge = edge(img_filter, 'canny', threshold * fudgeFactor);
figure, imshow(img_edge), title('edge detection')
% Dilate image to make the coin edges complete without holes
se_disk = strel('disk',4);
se_line1 = strel('line',3,100);
se_line2 = strel('line',3,100);
img_dilated = imdilate(img_edge, se_disk);
img_dilated = imdilate(img_dilated, [se_line1 se_line2]);
figure, imshow(img_dilated), title('dilate')
% Remove small objects (noise) and fill complete objects
img_clearborder = imclearborder(img_dilated, 4);
%figure, imshow(BWclear), title('cleared border image');
img_fill = imfill(img_clearborder, 'holes');
figure, imshow(img_fill), title('fill holes')
% Erode image to make a clear cut between objects
se_diamond = strel('diamond',2);
img_erode = imerode(img_fill,se_diamond);
for k=1:3
img_erode = imerode(img_erode,se_diamond);
end
img_nosmall = bwareaopen(img_erode,300);
figure, imshow(img_nosmall), title('erode')
[B, L] = bwboundaries(img_nosmall);
figure, imshow(label2rgb(L, @jet, [.5 .5 .5])), title('boundaries')
hold on
for k = 1:length(B)
boundary = B{k};
plot(boundary(:,2), boundary(:,1), 'w', 'LineWidth', 2)
end
stats = regionprops(L,img(:,:,1),...
'Area','Centroid','Orientation','EquivDiameter','MeanIntensity');
threshold = 0.80; % For differentiating coins from matches based on an objects circularity
coinCentroids = [];
coinIntensities = [];
matchCentroids = [];
matchAngles = [];
coinRatios = [];
for k = 1:length(B)
boundary = B{k};
delta_sq = diff(boundary).^2;
perimeter = sum(sqrt(sum(delta_sq,2)));
area = stats(k).Area;
metric = 4*pi*area/perimeter^2;
metric_string = sprintf('%2.2f',metric);
angle_string = sprintf('%2.2f',stats(k).Orientation);
centroid = stats(k).Centroid;
if metric > threshold
% Object is round, therefore a coin
coinCentroids = [coinCentroids; centroid];
coinIntensities = [coinIntensities; stats(k).MeanIntensity];
coinRatios = [coinRatios; stats(k).EquivDiameter/area];
else
% Object is a match
angle = stats(k).Orientation;
matchCentroids = [matchCentroids; centroid];
matchAngles = [matchAngles; angle];
end
plot(centroid(1),centroid(2),'ko');
% text(boundary(1,2)-35,boundary(1,1)+13,angle_string,'Color','y',...
% 'FontSize',14,'FontWeight','bold');
end
As you can see, I have identified which objects are coins and which objects are matches. But, I have big trouble identifying what value the coins have.
For example, Area/diameter of the coins gives the following results. I can't see any clear way to distinguish the different types of coins based solely on this data; the numbers are just too close.
0.0041 0.0042 0.0043 0.0043 0.0044 0.0045 0.0048 0.0048 0.0053 0.0054 0.0055 0.0055 0.0056
I tried getting the average color intensity from the starting picture of each coin too, but this did not help me separate the silver colored coins from the gold colored coins.
Mean intensity from the Red channel gives no information that there are 6 gold colored coins and 6 silver colored coins.
105.0104
105.4408
107.9070
112.4762
116.3412
127.3481
132.1418
137.9697
149.6601
159.2506
167.6910
181.1673
215.0395
Question: How can I identify the different coin values?
(Asked how to separate two joined objects here: Separate two overlapping circles in an image using MATLAB )
Thanks