reverse of bwmorph(BW, 'skel' )

9 views (last 30 days)
Ida Puggaard
Ida Puggaard on 19 Sep 2023
Edited: DGM on 30 Sep 2023
Hey
I have a segmented logical image which I have done the bwmorph(BW, 'skel' ) operation on the get the skeloton. I have then done some operations on the skeleton such as breaking up pieces. I would like for these changes to be applied to the segmented image. Is there a way to reverse the bwmorph(BW, 'skel' ) with my new skeleton such that the operations done on the skeleton is applied to the original segmented image?
  1 Comment
DGM
DGM on 19 Sep 2023
The answer depends on how altered the skeleton and how you expect that change to be extended to the original blob.

Sign in to comment.

Answers (3)

Akash
Akash on 29 Sep 2023
Hi Ida,
I understand that you have a segmented logical image and have performed the `bwmorph(BW, 'skel')` operation to obtain the skeleton. Subsequently, you have made modifications to the skeleton and would like to apply these changes to the original segmented image by reversing the `bwmorph(BW, 'skel')` operation.
To address your question, you can use the following code to achieve this. This code applies an inverse distance transform to recreate the changes made to the skeleton and applies them to the original segmented image:-
% Load the binary image
BW = imread('tree2.png');
BW = im2bw(BW);
imshow(BW);
% Apply skeletonization
skel = bwmorph(BW, 'skel');
% Calculate the distance transform
D = bwdist(~BW);
% Create a blank image for inverse distance transform
[r, c] = size(D);
BW2 = false(r, c);
% Apply inverse distance transform
for j = 1:c
for i = 1:r
if skel(i, j) == 0
continue;
end
radius = D(i, j);
[X, Y] = meshgrid(1:c, 1:r);
mask = (X - j).^2 + (Y - i).^2 <= radius.^2;
BW2(mask) = true;
end
end
imshow(BW2)
Hope it helps.
Thanks,
Akash.
  1 Comment
DGM
DGM on 30 Sep 2023
Edited: DGM on 30 Sep 2023
This doesn't even do what was requested. This is just some bot-generated nonsense that amounts to a convoluted and expensive dilation by 1px.
OP is working with a modified skeleton, which this answer explicitly acknowledges, and then completely ignores.

Sign in to comment.


Image Analyst
Image Analyst on 30 Sep 2023
I don't believe the other answer will maintain separation of the pieces you split apart. It looks like it will merge them together again. It was possibly generated by a chatbot.
What I would try is to use bwmorph() with the 'thicken' option.
thickenedImage = bwmorph(BW, 'thicken', n);
I would make n large because different parts of the blobs were eroded by different distances to produce the skeleton. Then you can AND the thickened image with the original segmented image:
splitImage = thickenedImage & BW;
This should give you the original binary image but with the black separation lines in there splitting your blobs into the pieces that you want.
  1 Comment
DGM
DGM on 30 Sep 2023
Edited: DGM on 30 Sep 2023
Thickening a lean 8-connected skeleton may produce unexpected results if it's not dilated or otherwise made 4-connected. It's useful to know how exactly the skeleton has been split, otherwise our attempts to preprocess it may "unsplit" the skeleton again (e.g. dilation)
The 'diag' option might be one option that has a lower risk of causing problems.
% an image
inpict = imread('d.png')>0;
imshow(inpict,'border','tight')
sk = bwmorph(inpict,'skel',Inf); % get skeleton
bp = bwmorph(sk,'branchpoints'); % get branchpoints
% make it obvious that segments are not connected
% this is just for visual clarity of the demo
bp = imdilate(bp,ones(21));
sk = sk & ~bp; % break the skeleton
% can't specify FG connectivity with bwmorph()
% so we need to actually preprocess the skeleton
sk = bwmorph(sk,'diag');
% thicken the broken skeleton
skth = bwmorph(sk,'thicken',Inf);
% show the skeleton and thickened skeleton
skcomp = imfuse(sk,skth);
imshow(skcomp,'border','tight')
% combine with original blob
outpict = inpict & skth;
imshow(outpict,'border','tight')
... of course, some of the narrow lines won't render here.

Sign in to comment.


DGM
DGM on 30 Sep 2023
Edited: DGM on 30 Sep 2023
Here's another idea using distance transform and watershed(). This uses the same blob and skeleton as in my prior comment.
% an image
inpict = imread('d.png')>0;
sk = bwmorph(inpict,'skel',Inf); % get skeleton
bp = bwmorph(sk,'branchpoints'); % get branchpoints
% make it obvious that segments are not connected
% this is just for visual clarity of the demo
bp = imdilate(bp,ones(21));
sk = sk & ~bp; % break the skeleton
% get the watershed ridgelines
skth = logical(watershed(bwdist(sk)));
% combine with original blob
outpict = inpict & skth;
imshow(outpict,'border','tight')

Products


Release

R2022a

Community Treasure Hunt

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

Start Hunting!