Bound an object within an image and fill that object with white

10 次查看(过去 30 天)
I'm attempting to fill an image that has red particles with very 'jagged' edges. I also have images of white particles on a black background and black particles on a white background, so I'm trying to find something general. I plan to later measure the width of the 'whited out' cylinder.
Here's the image:
Initially, I was using the following line of code for black particles on a white background:
A = imread(filename);
C = imcomplement(A);
C = im2bw(C, 150/255);
SE = strel('disk',10);
B = imclose(C, SE);
which produced:
This is just ok, but the boundaries aren't very precise.
I then tried the following, keeping in mind that I had red particles on a white background.
A = imread(filename);
C = imcomplement(A);
blueChannel = C(:, :, 3);
C = im2bw(blueChannel, 0.3);
B = imfill(C,'holes');
This produces the following image:
The edges are more precise, but this method is unfavorable because:
A) it is not general
B) There are are gaps left from the string
Now, I could use the strel command and fill these, but again, that creates an imprecise boundary along the edge of the column. I would prefer to fill it in such a way that connects the two closest white pixels along the outer boundary of a gap.
I've been looking into the edges function, as well as the different edge methods, but these end up just tracing lines around my object, which hasn't really helped me so far.
I feel like the imcomplement images are actually pretty close, from the code:
A = imread(filename);
C = imcomplement(A);
If only I could edit my measuring code (outlined below) to say something along the lines,
"Does the current line have a pixel that is not dark grey or black? Ff so, measure the width of the pixels that are not dark grey or black"
This still might not work though, due to the fact that the string is complemented to black.
From the image using red particles:
From the image using the Black particles:
Just as a heads up, I use the following lines of code to find the width of the cylinders im my images:
%{
"x1(idx) = (find(B(j,:),1,'last')+1)-find(B(j,:),1,'first')"
finds the width of the 1's within the matrix. "(find(B(j,:),1,'last')+1)"
finds the first instance of a non-zero value, where the first instance
is indicated by the 1, and 'last' tells the function to move from right
to left. We add the 1 here (+1) because the find function returns the
column index of the first non-zero value and, without the +1, we would actually
be finding the width-1.
%}
info = imfinfo(filename);
x1 = zeros(0, info.Height);
y1 = zeros(0, info.Height);
idx = 1;
for j = 1:info.Height
if any(B(j,:))==1;
x1(idx) = (find(B(j,:),1,'last')+1)-find(B(j,:),1,'first');
y1(idx) = j;
idx = idx+1;
end
end
FinalStruct(i).width = x1;
FinalStruct(i).indexwidth = y1;
A big, huge thanks in advance to anyone who even manages to read all of this!

采纳的回答

Image Analyst
Image Analyst 2019-9-24
How about using the Color Thresholder App to get the thresholds in HSV color space? See attached m-file for a full demo. I did a color segmentation to get the background, then inverted the mask, filled it, and then took the largest blob.
There is still a little bit of the metal cap getting in because it seems to be an aluminum ring that is taking on some of the pink color. I suggest you cover that top ring with black electrical tape. Other than that it seems to be pretty accurate to me.
0001 Screenshot.png

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Image Segmentation and Analysis 的更多信息

标签

产品


版本

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by