Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Separating objects in an image

Asked by Zoran on 22 Aug 2014
Latest activity Commented on by Zoran on 22 Aug 2014

Hi,

I'm trying to count objects in an image and the matlab script I wrote works pretty well but some objets are touching (in other image they are even overlapping) and it counts only for one instead of two. I am trying to use the bwdist function associated to the watershed function to separate these objects but it doesn't work pretty well: it cuts my objets at many part where it shouldn't and the counting is much worse.

If somebody could explain me how to proceed in other to separate only the good particles (the 2 touching at the right of my image) I would be grateful.

link for image: download the plastic image

Here is my code (if you run it a lot of figures will appear):

Sorry for writing the comments in french =P

clear all;
k=1; % indice pour la numérotation des images
I=imread('Images particules/DSC_0037.jpg');
figure(k)
k=k+1;
imshow(I);
I_hsv=rgb2hsv(I);
figure(k)
k=k+1;
imshow(I_hsv);
I_h=I_hsv(:,:,1);
I_s=I_hsv(:,:,2);
I_v=I_hsv(:,:,3);
figure(k)
k=k+1;
imshow(I_h)
figure(k)
k=k+1;
imshow(I_s)
figure(k)
k=k+1;
imshow(I_v)
%% Hue
[Gx, Gy] = imgradientxy(I_h);
[Gmag, Gdir] = imgradient(Gx, Gy);
% figure(k);
% k=k+1;
% imshowpair(Gmag, Gdir, 'montage');
I_bw1=Gmag>mean(quantile(Gmag,0.99));
figure(k);
k=k+1;
imshowpair(Gmag,I_bw1,'montage');
%% Saturation
[Gx, Gy] = imgradientxy(I_s);
[Gmag, Gdir] = imgradient(Gx, Gy);
% figure(k);
% k=k+1;
% imshowpair(Gmag, Gdir, 'montage');
I_bw2=Gmag>mean(quantile(Gmag,0.99));
figure(k)
k=k+1;
imshowpair(Gmag,I_bw2,'montage');
%% Variance
[Gx, Gy] = imgradientxy(I_v);
[Gmag, Gdir] = imgradient(Gx, Gy);
% figure(k);
% k=k+1;
% imshowpair(Gmag, Gdir, 'montage');
I_bw3=Gmag>mean(quantile(Gmag,0.99)); % choisir le bon quantile
figure(k)
k=k+1;
imshowpair(Gmag,I_bw3,'montage');
%% Addition images du gradient
I_recomp=I_bw1+I_bw2+I_bw3;
figure(k);
k=k+1;
imshow(I_recomp);
%% Dilatation - fill - erosion
% Element structurant diamond
% Dilatation
SE=strel('octagon',3); % doit être un multiple de 3 !
I_dil=imdilate(I_recomp,SE);
% figure(k)
% k=k+1;
% imshow(I_dil);
% Fill
I_fill=imfill(I_dil,'holes');
% Erosion
I_er=imerode(I_fill,SE);
% figure(k)
% k=k+1;
% imshow(I_er);
%% Elimination du bruit en appliquant un imerode <taille minimale des plastiques en pixels
% Erosion - dilatation
SE=strel('octagon',6); % mesurer la taille maximale d'un plastic en pixel avec imdistline !
I_bruit=imdilate(imerode(I_er,SE),SE);
figure(k)
k=k+1;
imshow(I_bruit);
%% Séparation des particules avec watershed
I_bwdist=-bwdist(~I_bruit);
figure(k);
k=k+1;
imshow(I_bwdist,[]);
I_water=watershed(I_bwdist);
I_bruit(I_water==0)=0;
figure(k);
k=k+1;
imshow(I_bruit);
%% Comptage des particules
cc=bwconncomp(I_bruit);
cc.NumObjects
L=labelmatrix(cc);
RGB_label=label2rgb(L);
figure(k);
k=k+1;
imshow(RGB_label);

0 Comments

Zoran

1 Answer

Answer by Image Analyst on 22 Aug 2014

1 Comment

Zoran on 22 Aug 2014

Thank you for these precious links. Watershed segmentation seems is certainly the answer to my problem.

The problem is I got an over segmentation while applying the function. I tried to eliminate some "holes" that are responsible for that using imextendmin and imimposemin and the result is some what better. But some of my plastic are now cut in new pieces (they should stay compact) and the waterline is cutting my pieces also.

I don't see how I can do to get only one minima per particle. And how can I apply foreground and background marker method to my problem ?

Here's what I changes in my script:

I_bwdist=-bwdist(~I_bruit);
figure(k);
k=k+1;
imshow(I_bwdist,[]);
mask = imextendedmin(I_bwdist,25); % choisir la bonne valeur
figure(k);
k=k+1;
imshowpair(I_bruit,mask,'blend');
I_bwdist2 = imimposemin(I_bwdist,mask);
I_water=watershed(I_bwdist2);
I_bruit(I_water==0)=0;
figure(k);
k=k+1;
imshow(I_bruit);
Image Analyst

Contact us