Image segmentation of these pellets
조회 수: 59 (최근 30일)
이전 댓글 표시
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
답변 (2개)
Taylor
2024년 4월 1일 20:07
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
DGM
2024년 4월 1일 21:30
편집: DGM
2024년 4월 1일 21:31
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')
Image Analyst
2024년 4월 2일 18:26
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
참고 항목
카테고리
Help Center 및 File Exchange에서 Image Processing Toolbox에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!