Effacer les filtres
Effacer les filtres

Bubbles edge detection to quantify size distribution

7 vues (au cours des 30 derniers jours)
Gilles MARY
Gilles MARY le 11 Avr 2023
Commenté : Gilles MARY le 12 Avr 2023
Dear Matlab colleagues,
I want to detetect the outline ouf the bubbles on that kind of microscopic pictures, so that I could quantify the size distribution. I try to apply differents steps to enhance contrast and clean background (locllapfilt, imbinarize) before applying the edge fonction but, despite erosions and dilatations the result is not sharp enought.
I wondering if there is a preprocessing step which can make the bubbles well delimited or an alternative way to get the bubble size distribution on that image ?
I thank you for the attention to my request.
If required, you will find hereafter the code I tried:
% lire l'image
I = imread('0006.tif');
% conversion RGB en niveaux de gris
Igs = im2gray(I);
figure
imshowpair(I,Igs,'montage')
title('Gray scale conversion')
% Filtre laplacien
sigma = 0.1;
alpha = 3.0;
numLevels = 20;
Illf = locallapfilt(Igs, sigma, alpha, 'NumIntensityLevels', numLevels);
figure, imshowpair(Igs,Illf,'montage')
title('LLF Image');
% Binarisation
Ibin = imbinarize(Illf,'adaptive','ForegroundPolarity','dark','Sensitivity',0.59);
figure
imshowpair(Illf,Ibin,'montage')
% Detection de contour
[~,threshold] = edge(Ibin,'sobel');
fudgeFactor = 2.0;
BWs = edge(Ibin,'sobel',threshold * fudgeFactor);
imshow(BWs)
figure
imshowpair(Igs,BWs,'montage')
title('Binary Gradient Mask')
% Dilatation d'image
se90 = strel('square',5);
se0 = strel('square',5);
BWsdil = imdilate(BWs,[se90 se0]);
figure
imshowpair(I,BWsdil,'montage')
title('Dilated Gradient Mask')
% Remplissage des vides
BWdfill = imfill(BWsdil,'holes');
imshowpair(I,BWdfill,'montage')
title('Binary Image with Filled Holes')
% Netoyage des contours
BWnobord = imclearborder(BWdfill,4);
imshowpair(I,BWnobord,'montage')
title('Cleared Border Image')
% Lissage
seD = strel('diamond',1);
BWfinal = imerode(BWnobord,seD);
BWfinal = imerode(BWfinal,seD);
imshowpair(I,BWfinal,'montage')
%imshow(BWfinal)
title('Segmented Image');
% visualisation du masque
imshow(labeloverlay(I,BWfinal))
title('Mask Over Original Image')

Réponses (1)

Ran Yang
Ran Yang le 11 Avr 2023
Conceptually, your edges aren't sharp enough because contour detection isn't the right algorithm for the task. You're trying to segment the edges of circles (using imbinarize), but then you're doing contour detection on that, which is giving you the edges of the edges of circles. So instead of doing contour detection, you should try to somehow infer edges directly from your Ibin.
Here's one way that I did this, though it can be better optimized.
I = imread('0006.jpg');
% correct uneven illumination and adjust contrast (alternative to your
% laplacian filter)
x0 = imadjust(imtophat(imcomplement(im2gray(I)), strel('disk', 50)));
x1 = imbinarize(x0, 'adaptive', 'sensitivity', 0.1); % define circle 'edges'
x2 = imclose(x1, strel('disk', 3)); % smooth and join together almost completed edges
x3 = bwmorph(x2, 'shrink', Inf); % shrink edges down to lines
x4 = bwmorph(x3, 'clean'); % remove points (which were originally incomplete circles/noise)
% remove background (note: this assumes [1 1] is always part of your bg,
% can use padarray to guarantee this if you do it in batch)
x5 = imfill(x4, [1 1]);
x6 = imcomplement(x5);
% label objects, make colorful figure
x7 = bwlabel(x6, 4);
figure, imshow(labeloverlay(I, x7));
You can then do a manually defined filter to get rid of the smallest objects (false positives), using regionprops. If you're confused about how we got here, I recommend you just do figure, imshow(x_) to see what's going on in each step.
There's yet another method that you might be interested in, called imfindcircles. I personally have found it too finicky to use in batch (lots of parameters to tune and small adjustments might make big differences), and it's also harder to get rid of false positives, but the code is much shorter.
x = locallapfilt(im2gray(I), 0.4, 0.1);
[c, r] = imfindcircles(x, [20 140], 'Sensitivity', 0.8, 'method', 'TwoStage');
figure, imshow(I), viscircles(c, r);
  1 commentaire
Gilles MARY
Gilles MARY le 12 Avr 2023
Impressive...
I'll will try to understand the different steps and optimize the process.
Deeply thanks for the time and the energy spent.

Connectez-vous pour commenter.

Community Treasure Hunt

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

Start Hunting!

Translated by