Segment and Separate overlapping crystals based on generated Skeleton
4 views (last 30 days)
Show older comments
Shahil Khan
on 18 Apr 2022
Answered: Image Analyst
on 18 Apr 2022
I am working with a dataset that has multiple overlapping crystalline structures. After segmentation, I am currently manually identifying overlapping structures which I think can be separated.
I use bwskele to generate a skeleton. I then remove points which are '0' as I only want the points that matter.
My thinking is that I can create a ROI based on the coordinates skeleton coordinates for each crystal. Sement the image based on the generated ROI and so then I can determine more accurate regionprop variables.
Does anyone have any advice on generateing an appropriate method so I can segment the crystal below into two separate crystals. The separation in this example is essentially like separating the two lines from the letter 't'
Sample image: https://ibb.co/3fy8v9D
Overlapped Crystal I am working with:
Skeleton generated:
Here is my code after segmentation:
%Extracting individual blobs to analyze
bboxlist = regionprops(mask, 'BoundingBox')
nBBox = length(bboxlist);
imgList = {};
imgList_BW = {};
%RGB images
for i = 1:nBBox
bbox = bboxlist(i).BoundingBox;
imgCrop = imcrop(maskRGB, bbox);
imgList{end+1} = imgCrop;
end
%Mask
for i = 1:nBBox
bbox = bboxlist(i).BoundingBox;
imgCrop = imcrop(mask, bbox);
imgList_BW{end+1} = imgCrop;
end
imTile = imtile(imgList);
imshow(imTile);
imTile_BW = imtile(imgList_BW);
imshow(imTile_BW);
size(imgList)
%Selecting an interesrting looking structure
ovl_img = imgList{34};
ovl_img_BW = imgList_BW{34};
imshow(ovl_img);
imshow(ovl_img_BW);
%Using in skeleton
mask = logical(rgb2gray(ovl_img)); % convert to black & white mask
mask = bwareafilt(mask,1); % take only the largest blob
%Plotting Skeleton
skeleton = bwskel(ovl_img_BW, 'MinBranchLength', 1);
imshow(skeleton)
branchPoints = bwmorph(skeleton, 'branchpoints');
endPoints = bwmorph(skeleton, 'endpoints');
[rowBranchPt, colBranchPt] = find(branchPoints == 1);
[rowEndPt, colEndPt] = find(endPoints == 1);
plot(colBranchPt(:), rowBranchPt(:), 'ro', 'MarkerSize',5,"LineWidth",1);
plot(colEndPt(:), rowEndPt(:), 'ro', 'MarkerSize',5,"LineWidth",1);
0 Comments
Accepted Answer
Image Analyst
on 18 Apr 2022
Try setting the 'MinBranchLength' parameter. However that makes no guarantee that the surviving branches will be roughly in a line. You might have to break the skeleton into segments and analyze them all to see which are collinear, then compute the lengths of those.
0 Comments
More Answers (0)
See Also
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!