MATLAB Answers

Hello, can anyone help me to find the count of mushrooms from an image?

조회 수: 8(최근 30일)
Voohitha  bojja
Voohitha bojja 2021년 9월 15일
댓글: Image Analyst 2021년 9월 22일
In this image if I have to find the number of mushrooms,how do I do it?I tried it this way but I could not get the correct number or approximate atleast.
clc;
clear all;
close all;
img=imread('testimage/mushroomgroup.jpg');
figure,
imshow(img);
%convert into grayscale image
img_gray=rgb2gray(img);
figure,
imshow(img_gray);
%convert to the binary veresion of the image
BW=im2bw(img_gray,0.65);
figure,
imshow(BW);
%complement
BW1=imcomplement(BW);
figure,
imshow(BW1);
%fill the holes to make solid object
BW2=imfill(BW1,'holes');
figure,
imshow(BW2);
%
BW3=bwareaopen(BW2,10);
%Now find the number of mushroom
mushrooms=bwconncomp(BW3);
disp("The total number of mushrooms are: ")
disp(mushrooms);

답변(1개)

Adam Danz
Adam Danz 2021년 9월 15일
편집: Adam Danz 2021년 9월 16일
I'm an enthusiastic novice in image analysis so I'm not confident that this is the best (or even a good) solution but it might help to get you started.
It's based on your code but uses imfindcircles to find black circles in the complement image. This results in many overlapping, redundant detected circles so an additional section cleans that up by taking the following steps,
  • For each detected circle, it computes the portion of black pixels within the circle.
  • It detects which circles are overlapping.
  • Using a threshold (overlapThreshold), it detects which circles are overlapping too much and selects one of them to represent a mushroom and removes the rest. The selected circle is the circle from the group that has the highest percentage of black pixels within the circle.
Lastly, it plots the final circles and writes the radius, portion of black pixels (%) and circle index number within each circle.
To see information about the circle with index n,
centers(n,:) % circle center
radii(n) % you guessed it, radius
blackPortion(n) % fraction of black pixels within the circle
See inline comments for details and footnotes.
As you can see, the results below contain two errors. Playing around with the parameters or cleaning up the image a bit more may help.
  1. Circle 19 is a false alarm. I have no idea why that's considered a circle.
  2. The mushroom under circle 18 was undetected. You can see this mushroom vanished when converting the image from grayscale to binary so you could start by adjusting the parameters in imbinarize.
img=imread('mushroomgroup.jpeg');
fig = figure();
tlo = tiledlayout(fig, 3, 4, 'Padding','tight','TileSpacing','none');
imshow(img, 'parent', nexttile());
title('Original')
%convert into grayscale image
img_gray=rgb2gray(img);
imshow(img_gray, 'parent', nexttile());
title('GrayScale')
%convert to the binary veresion of the image
BW=imbinarize(img_gray,'adaptive','Sensitivity',1); % [1,2]
imshow(BW, 'Parent', nexttile());
title('Binary')
%complement
BW1=imcomplement(BW);
imshow(BW1, 'Parent', nexttile());
title('Complement')
% ----- (I Commented-out this section, it wasn't helpful)
%fill the holes to make solid object
% BW2=imfill(BW1,'holes');
% figure,
% imshow(BW2);
%
% BW3=bwareaopen(BW3);
% Find black circles; return their centers and radii
[centers,radii,~] = imfindcircles(BW1,[60,90],... % [3]
'ObjectPolarity','dark','Sensitivity',0.97);
% Plot final result with circled mushrooms
imshow(BW1, 'Parent', nexttile([2,4]))
title('Complement with labels')
hold on
% To see the results before cleaning up circle-overlap, run this line.
% ch = viscircles(centers, radii, 'color', 'r');
% Clean up overlap: Step 1
% compute protion of circle that is black (blackPortion, 0:1)
nCircles = numel(radii);
[ximg, yimg] = meshgrid(1:size(BW1,2), 1:size(BW1,1));
blackPortion = nan(size(radii));
for i = 1:nCircles
mask = hypot(ximg-centers(i,1), yimg-centers(i,2)) < radii(1);
blackPortion(i) = mean(~BW1(mask));
end
% Clean up overlap: Step 2
% Determine which circles overlap by more than a threshold amount.
% Then select the circle with the greatest coverage of black pixels.
overlapThreshold = .6; % minimum allowed overlap normalized by radii. Lower values accept more overlap.
distanceToCenters = squareform(pdist(centers)) ./ (radii*2);
[row,col] = find(tril(distanceToCenters < overlapThreshold));
selection = false(nCircles,1);
for i = 1:nCircles
tempRows = row(col==i);
tempRows(isnan(tempRows)) = [];
if isempty(tempRows); continue; end
[~, maxIdx] = max(blackPortion(tempRows));
row(ismember(row,setdiff(tempRows, tempRows(maxIdx)))) = NaN;
selection(tempRows(maxIdx)) = true;
end
% Remove overlapping circles that were not selected
centers(~selection,:) = [];
radii(~selection) = [];
blackPortion(~selection) = [];
% Plot the identified circles
ch = viscircles(centers, radii, 'color', 'r');
% Label the radii, coverage (%), and circle ID
th = text(centers(:,1), centers(:,2), compose('r = %.1f\n%.1f%%', radii, blackPortion*100), ...
'HorizontalAlignment', 'Center', 'VerticalAlignment', 'Top', 'Color', 'c');
th2 = text(centers(:,1), centers(:,2), compose('%d', 1:numel(radii)), ...
'HorizontalAlignment', 'Center', 'VerticalAlignment', 'Bottom', 'Color', 'y');
fprintf('%d mushrooms found.\n', numel(radii));
% Footnotes
% [1] Use imbinarize instead of im2bw.
% [2] Play around with the imbinarize options if needed; small changes to the
% sensitivity parameter will have a noticible impact on the final results.
% [3] In imfindcircles, the radii range ([60,90]) was chosen based on the
% example image. The results are *highly* senstive to the "senstivity"
% parameter which makes this much less robust when applied to other
% images. Consider playing around with imfindcircles option or use a
% different method.
  댓글 수: 5
Image Analyst
Image Analyst 2021년 9월 22일
Try to put your mushrooms on a black background. Then since mushrooms are bright and the background is dark you can get a mask
mushroomMask = grayImage > someThresholdValue; % This is an image.
% To get the number of mushroom pixels
numMushroomPixels = nnz(mushroomMask);
% To get the area fraction:
areaFraction = numMushroomPixels / numel(mushroomMask);
% To get percent area multiply the area fraction by 100
percentArea = areaFraction * 100;

댓글을 달려면 로그인하십시오.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by