Tortuosity of blood vessels

Illustration
Tri Rowstenkowski - 2022-02-12T10:51:10+00:00
Question: Tortuosity of blood vessels

Hello,   I am trying to calculate the Tortuosity of blood vessels. (Vessel tortuosity is calculated as the sum of branch lengths divided by the sum of the euclidean distance between their end points).   I have the following questions: How to calculate the lengths of both actual branches and the imaginary straight lines between nodes How do I mark the vessel branches (orange) and the branch nodes (yellow) as shown in the picture. I am calculating "spinelength" as the sum of all pixels. How do I calculate individual branch lengths? Any suggestions in preprocessing would be appreciated.   clc; clear; close all % Read the image I=imread('VAD.png'); figure,imshow(I) %convert it to gray scale I_gray=rgb2gray(I); %Sharpen the image b = imsharpen(I_gray,'Amount',8); h = fspecial('average', [3 3]); b = imfilter(b, h); %choose brighter objects Bina=b>150 figure,imshow(Bina); se = strel('cube',3) erodedBW = imerode(Bina,se); %Remove small objects from binary image BW2 = bwareaopen(Bina,100) figure,imshow(BW2); skelImage = bwskel(BW2, 'MinBranchLength', 10); MinBranchLength = round(sum(skelImage(:))/2) skelImage = bwskel(BW2,'MinBranchLength',MinBranchLength); figure,imshow(skelImage) endpointImage = bwmorph(skelImage, 'endpoints'); [rows, columns] = find(endpointImage) spineLength = sum(skelImage(:)) straightLineDistance = sqrt((columns(2) - columns(1))^2 + (rows(2) - rows(1))^2) tortuosity = spineLength / straightLineDistance  

Expert Answer

Profile picture of Prashant Kumar Prashant Kumar answered . 2025-11-20

To calculate the tortuosity of blood vessels and achieve your objectives, follow these steps:


1. Input Data and Preprocessing

You need an image or data representation of the blood vessels. If the image is raw:

  • Apply a contrast enhancement to highlight vessels.
  • Use edge detection techniques (e.g., Canny or Sobel) to extract the vessel structure.
  • Use skeletonization to reduce the vessels to a one-pixel-wide skeleton (e.g., bwmorph in MATLAB or skeletonize in Python).

MATLAB example for preprocessing:

 

% Read and preprocess the image
img = imread('vessel_image.jpg'); % Replace with your image path
gray_img = rgb2gray(img); % Convert to grayscale
enhanced_img = imadjust(gray_img); % Contrast enhancement

% Binary image and skeletonization
binary_img = imbinarize(enhanced_img);
skeleton = bwmorph(binary_img, 'skel', Inf);

% Display skeletonized image
imshow(skeleton);
title('Skeletonized Vessel Structure');

2. Calculate Actual and Euclidean Lengths

  • Actual Length (Branch Length): Count the number of pixels along the skeleton for each branch.
  • Euclidean Length: Compute the Euclidean distance between branch endpoints.

To achieve this:

  1. Identify branch nodes (points where vessels bifurcate).
  2. Label the segments between branch nodes.
  3. Compute the pixel count and endpoint distances for each segment.

MATLAB example:

 

% Label branch nodes and endpoints
branch_points = bwmorph(skeleton, 'branchpoints');
end_points = bwmorph(skeleton, 'endpoints');

% Find connected components (segments)
[labeled_segments, num_segments] = bwlabel(skeleton);

% Calculate lengths
branch_lengths = zeros(num_segments, 1);
euclidean_lengths = zeros(num_segments, 1);

for i = 1:num_segments
    % Extract individual segment
    segment = (labeled_segments == i);
    
    % Calculate actual length (number of pixels)
    branch_lengths(i) = sum(segment(:));
    
    % Identify endpoints of the segment
    [rows, cols] = find(segment);
    endpoints = find(end_points & segment);
    if length(endpoints) == 2
        [r1, c1] = ind2sub(size(segment), endpoints(1));
        [r2, c2] = ind2sub(size(segment), endpoints(2));
        % Calculate Euclidean distance
        euclidean_lengths(i) = sqrt((r2 - r1)^2 + (c2 - c1)^2);
    end
end

% Calculate tortuosity
tortuosity = sum(branch_lengths) / sum(euclidean_lengths);
fprintf('Tortuosity: %.2f\n', tortuosity);

3. Marking Branches and Nodes

Use bwlabel or connected component analysis to label branches and overlay markings for nodes and branches.

MATLAB example:

% Mark branch nodes and endpoints
imshow(skeleton);
hold on;
[y_branch, x_branch] = find(branch_points);
plot(x_branch, y_branch, 'yo', 'MarkerSize', 10, 'LineWidth', 2); % Yellow branch nodes

[y_end, x_end] = find(end_points);
plot(x_end, y_end, 'ro', 'MarkerSize', 10, 'LineWidth', 2); % Red endpoints

title('Branch Nodes (Yellow) and Endpoints (Red)');
hold off;

4. Improving Skeleton for Accuracy

To improve accuracy:

  1. Remove small spurs using bwmorph(img, 'spur', n) to clean small noise.
  2. Smooth skeleton using morphological operations or spline fitting.
  3. Manually inspect or validate branch nodes for unusual bifurcations.

Summary

  • Use skeletonization to simplify the vessel structure.
  • Detect branch nodes and endpoints using morphological operations.
  • Calculate actual and Euclidean lengths for segments.
  • Compute tortuosity as the ratio of actual length to Euclidean length.
  • Visualize nodes and segments to validate the results.

Let me know if you'd like further clarification or additional details!


Not satisfied with the answer ?? ASK NOW

Get a Free Consultation or a Sample Assignment Review!