Effacer les filtres
Effacer les filtres

Image segmentation of these pellets

5 vues (au cours des 30 derniers jours)
Saye Vikram
Saye Vikram le 29 Mar 2024
Commenté : Saye Vikram le 6 Avr 2024
Hello, I have a task which needs me to perform image segmentation for every pellet for this image (pellet being defined as every "flat-ish" pellet that is visible from the side of the screen, no pellets that I cannot see the whole side-view of) :
I tried to use watershed segmentation and Distance transform in order to separate out the pellets as below:
clear
rgb = imread("matlab_test.png");
I = im2gray(rgb);
gmag = imgradient(I);
L = watershed(gmag);
Lrgb = label2rgb(L);
se = strel("disk",5);
Io = imopen(I,se);
Ie = imerode(I,se);
Iobr = imreconstruct(Ie,I);
Ioc = imclose(Io,se);
Iobrd = imdilate(Iobr,se);
Iobrcbr = imreconstruct(imcomplement(Iobrd),imcomplement(Iobr));
Iobrcbr = imcomplement(Iobrcbr);
fgm = imregionalmax(Iobrcbr);
I2 = labeloverlay(I,fgm);
se2 = strel(ones(3,3));
fgm2 = imclose(fgm,se2);
fgm3 = imerode(fgm2,se2);
fgm4 = bwareaopen(fgm3,20);
I3 = labeloverlay(I,fgm4);
bw = imbinarize(Iobrcbr);
D = bwdist(bw);
DL = watershed(D);
bgm = DL == 0;
gmag2 = imimposemin(gmag, bgm | fgm4);
L = watershed(gmag2);
labels = imdilate(L==0,ones(3,3)) + 2*bgm + 3*fgm4;
I4 = labeloverlay(I,labels);
Lrgb = label2rgb(L,"jet","w","shuffle");
figure
imshow(I)
hold on
himage = imshow(Lrgb);
himage.AlphaData = 0.3;
title("Colored Labels Superimposed Transparently on Original Image")
This code however only segments to a certain extent, as such:
How do I tweak my code so that it segments every individual pellet as much as possible?
  1 commentaire
DGM
DGM le 1 Avr 2024
Modifié(e) : DGM le 1 Avr 2024
Edited only to attach the images locally.

Connectez-vous pour commenter.

Réponses (2)

Taylor
Taylor le 1 Avr 2024
Have you tried a different colorspace? I converted the image to HSV and used the Color Thresholder app. Just with that I was able to get the following mask. The function below will recreate the mask for you.
function [BW,maskedRGBImage] = createMask(RGB)
%createMask Threshold RGB image using auto-generated code from colorThresholder app.
% [BW,MASKEDRGBIMAGE] = createMask(RGB) thresholds image RGB using
% auto-generated code from the colorThresholder app. The colorspace and
% range for each channel of the colorspace were set within the app. The
% segmentation mask is returned in BW, and a composite of the mask and
% original RGB images is returned in maskedRGBImage.
% Auto-generated by colorThresholder app on 01-Apr-2024
%------------------------------------------------------
% Convert RGB image to chosen color space
I = rgb2hsv(RGB);
% Define thresholds for channel 1 based on histogram settings
channel1Min = 0.009;
channel1Max = 0.112;
% Define thresholds for channel 2 based on histogram settings
channel2Min = 0.103;
channel2Max = 0.275;
% Define thresholds for channel 3 based on histogram settings
channel3Min = 0.347;
channel3Max = 0.687;
% Create mask based on chosen histogram thresholds
sliderBW = (I(:,:,1) >= channel1Min ) & (I(:,:,1) <= channel1Max) & ...
(I(:,:,2) >= channel2Min ) & (I(:,:,2) <= channel2Max) & ...
(I(:,:,3) >= channel3Min ) & (I(:,:,3) <= channel3Max);
BW = sliderBW;
% Initialize output masked image based on input image.
maskedRGBImage = RGB;
% Set background pixels where BW is false to zero.
maskedRGBImage(repmat(~BW,[1 1 3])) = 0;
end
  2 commentaires
DGM
DGM le 1 Avr 2024
Modifié(e) : DGM le 1 Avr 2024
This doesn't answer the question. The goal is to segment individual pellets. This does not do that.
inpict = imread('pellets.png');
mk = mymask(inpict); % create a mask using global thresholds
mk = bwareaopen(mk,100); % get rid of a thousand tiny specks
S = regionprops(mk,'area'); % look at the distribution
% generate an alternating CT
CT = hsv(numel(S));
CT(2:2:end,:) = flipud(CT(2:2:end,:));
% the result is one giant conglomerate blob
% and several smaller conglomerate blobs
alpha = 0.8;
outpict = labeloverlay(inpict,bwlabel(mk), ...
'transparency',1-alpha,'colormap',CT);
imshow(outpict,'border','tight')
Saye Vikram
Saye Vikram le 2 Avr 2024
Great response and answer first off. I just wanted to ask, would this not treat the whole red-portion as one giant blob? Is there no way to segment that portion so you can retrieve information about each pellet in that red-region?

Connectez-vous pour commenter.


Image Analyst
Image Analyst le 2 Avr 2024
It would be very very difficult to segment every single individual pellet, particulary since some are very small, some are "touching" adjacent pellets, and they have every conceivable shape, even down to powder particles.
In cases like these you need to really ask yourself what is really needed. You have some attribute that you need to quantify. Perhaps it's shape, perhaps it's volume of pellets in the container, perhaps it's just the quality of the pellet shapes, perhaps it's the colors of the pellets. Perhaps it's how easily they flow in a pipe or how easily they can get crushed or burned. Maybe you need to run the pile of pellets through sieves of different sizes and weigh them or photograph them.
It's difficult to answer the question because we don't know the full context. Finding evey pellet would be difficult even if you were to tediously hand-trace each pellet. So we need to find something else -- some other metric -- that will correlate with the attribute that you really need to know. For example, maybe we can segment the whole pile into one blob and look at the standard deviation of gray levels in that region and maybe that correlates well with how easily a pile can flow in a pipe, or get crushed, or burn completely. Maybe you can then make a plot (by analyzing the range of samples you have) that relates standard deviation to crushability. Then once you have that plot (calibration curve) created, you can predict the crushability of the particles by using it to input the StDev and getting out an estimate of crushability.
So please tell us what you REALLY need to know and we'll tell you if you really need to find each and every pellet or is there some bulk measurement that will give us the correlation we need. You may not need to find every pellet like you asked us -- there may be a much easier way. See
  1 commentaire
Saye Vikram
Saye Vikram le 6 Avr 2024
Sorry caught up with stuff, could not get to your response. What I REALLY need is either the center position and orientation (angle relative to the horizontal) of each pellet across a whole video in order to form a Langrangian description of flow. I either need that OR I need the average of Xi (Position of a pellet i) or Thetai in a small spatial region at time T in order to form a Eulerian description of flow. Ultimately I am trying to find the governing equations for X(x, y, t) and Theta(x, y, t)

Connectez-vous pour commenter.

Catégories

En savoir plus sur Image Processing Toolbox dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by