Segment and Separate overlapping crystals based on generated Skeleton

4 views (last 30 days)
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'
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);

Accepted Answer

Image Analyst
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.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!