Clear Filters
Clear Filters

Connecting branch points using a straight line as dictated by the skeleton

31 views (last 30 days)
I want to connect the branch points and endpoints of a skeleton (see sample skeleton below) via straight lines. However, the lines should be along the path of the skeleton. It's like "straightening" the skeleton. I've drawn a sample picture below describing how the branchpoints should be connected by the blue straight lines.
I'm thinking that this would probably involve a traversal algorithm.
  2 Comments
WR
WR on 28 Jun 2024 at 10:15
Yes that's right. Basically, getting rid of the "curved" lines in the skeleton by connecting the nodes with straight lines instead

Sign in to comment.

Answers (1)

Image Analyst
Image Analyst on 28 Jun 2024 at 12:27
Why? Why do you think you need that?
Here's what I'd do:
  1. Call bwmorph to find the branchpoints.
  2. Loop over each branchpoint and find the closest other branchpoint.
  3. In a new image, use linspace to determine the "in between" coordinates and set them to true.
Here's a start, with a "to do for you":
% Initialization steps.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 18;
skelImage = logical(imread('skeleton.png'));
% The sample image has a huge white frame around it, so get rid of that.
skelImage = imclearborder(skelImage);
subplot(2, 2, 1);
imshow(skelImage);
bpImage = bwmorph(skelImage, 'Branchpoints');
subplot(2, 2, 2);
imshow(bpImage);
[bpRows, bpCols] = find(bpImage)
fprintf('Found %d branchpoints.\n', numel(bpRows))
% It's hard to see them so put a marker over each one.
hold on;
plot(bpCols, bpRows, 'r.', 'MarkerSize', 10);
outputImage = false(size(bpImage));
for k = 1 : numel(bpRows)
x1 = bpCols(k);
y1 = bpRows(k);
% Find distances to others.
distances = sqrt((x1 - bpCols) .^ 2 + (y1 - bpRows) .^ 2);
% Find mins
[minDistances, indexes] = sort(distances, 'ascend');
% IMPORTANT. TO DO FOR YOU.
% Make sure we don't "backtrack" by making sure we have not
% used these exact (x1, y1) and (x2,y2) before by seeing if
% both those points are true in the output image.
x2 = bpCols(indexOfClosest);
y2 = bpRows(indexOfClosest);
% Find number of pixels between the two points.
numSamples = ceil(sqrt((x2-x1)^2 + (y2-y1)^2));
% Make sure we won't have any gaps due to rounding.
% Then get a line between the two points.
x = linspace(x1, x2, ceil(2*numSamples));
y = linspace(y1, y2, ceil(2*numSamples));
% Set those pixels to true in the output image
for k2 = 1 : numel(x)
row = round(y(k2));
col = round(x(k2));
outputImage(row, col) = true;
end
end
subplot(2, 2, 2);
imshow(outputImage);

Community Treasure Hunt

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

Start Hunting!