Identify objects in images

25 views (last 30 days)
U X
U X on 22 Nov 2021
Commented: Rena Berman on 13 Dec 2021
image = imread(['pills_hard.jpg']);
imtool(image);
% gn(I);
gray_img = rgb2gray(image);
%imshow(image);
imshow(gray_img);
imtool(gray_img);
BW = imbinarize(gray_img,'adaptive','ForegroundPolarity','dark','Sensitivity',0.47);
figure;
imshow(BW);
% computes the compliment of the image
X = imcomplement(BW);
p4 = imfill(X, 'holes');
figure;
imshow(p4);
SE = strel('disk', 5);
p5 = imerode(p4, SE);
[L,num] = bwlabel(p5);
disp(num);
So I am provided a series of images with different difficulty levels, the aim is to count the pills, and with images containing different pills, identify and count them respectively. I made some progress with simpler images using imclose() and imsubtract(), or binarize grayscale image with different sensitivity level. But with shadows and connections of pills and reflection of omega-oil pills, I couldn't find a way to successfully produce outcomes for these harder images. I'm more than grateful if anyone can shed some light on this, thanks in advance. I have attached the code that I used.
  1 Comment
Rena Berman
Rena Berman on 13 Dec 2021
(Answers Dev) Restored edit

Sign in to comment.

Answers (1)

Image Analyst
Image Analyst on 22 Nov 2021
First of all, get a better background, like all white or something. Then background correct and threshold. Then measure features such as Area and MajorAxisLength to filter out the type of pills you want.
mask = correctedImage > someThreshold;
props = regionprops(mask, 'Area', 'MajorAxisLength', 'MinorAxisLength');
allAreas = [props.Area];
aspectRatios = [props.MajorAxisLength] ./ [props.MinorAxisLength]
smallPillIndexes = find(allAreas < someValue);
smallPillsMask = ismember(mask, smallPillIndexes);
bigPillsMask = mask & ~smallPillsMask;
Pretty easy but see my Image Segmentation Tuturial if you need help, or write back here.
You might also look into the Color Thresholder App on the Apps tab of the tool ribbon to get code to identify the colored background.
  8 Comments
Image Analyst
Image Analyst on 23 Nov 2021
Strange they would give you such a difficult problem with no discussion of possible methods to solve it.
First I'd try to do a background correction by estimating the background, maybe by using the Color Thresholder. Then use scatteredInterpolant() to fill in the background everywhere. Then I'd divide your image by the background to compensate for the fact that there is lens shading and your light exposure is not the same everywhere. I attach a demo for that.
Next I'd try the Color Thresholder again on the background corrected image to see if you can get the pills without the shadows. Try HSV color space.
It's possible you might need a different masking function for each pill color, or you might be able to just get the background and invert it to get all the pills.
Since some of the pills are touching, after you get the mask you'll need to erode it a bit with imerode() to separate them. Or else use watershed:

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!