Extracting Vessel Dimensions from 2D Fluorescence Microscopy Images in MATLAB
Show older comments
I am working with fluorescence microscopy images of blood vessels in the brain, stored as HDF5 files (.h5). My goal is to extract vessel dimensions (diameters) from each frame in a time series and analyze how they change over time.
Currently, I am using MATLAB to:
- Load the .h5 file and extract individual frames.
- Apply Gaussian filtering and contrast enhancement to improve vessel visibility.
- Perform edge detection (Canny) and skeletonization to extract vessel centerlines.
- Compute vessel diameters using the Euclidean distance transform from the skeleton.
However, I am running into several issues:
- Edge detection is inconsistent and picks up artifacts inside the vessel.
- The skeleton sometimes extends beyond the vessels or is not continuous.
- Extracted diameters appear constant, even when the vessel visibly changes size.

Current Approach in MATLAB
Here’s the code I am using to manually select vessels and compute diameters:
vars = dloc.saved_vars;
img = dloc.load_var("reference_img");
img = squeeze(img(:,:,1));
frame_idx = 1000;
frame = double(h5read(dloc.path, '/recording', [1,1,1,frame_idx], [512, 512,1,1]));
frame_smooth = imgaussfilt(frame, 2);
% Create a normalized & contrast-enhanced frame for Canny
frame_enhanced = mat2gray(frame_smooth);
frame_enhanced = imadjust(frame_enhanced, stretchlim(frame_enhanced, [0.01, 0.99]));
%% --- Frangi Vesselness Filter ---
[I_vessel, ~] = FrangiFilter2D(frame_enhanced, struct( ...
'FrangiScaleRange', [1 5], ...
'FrangiScaleRatio', 2, ...
'FrangiBetaOne', 0.5, ...
'FrangiBetaTwo', 15, ...
'BlackWhite', true));
bw_vessel = I_vessel > 0.1;
bw_vessel = bwareaopen(bw_vessel, 100);
bw_vessel = imclose(bw_vessel, strel('disk', 3));
skeleton = bwskel(bw_vessel);
skeleton = bwmorph(skeleton, 'spur', 30);
distance_map = bwdist(~bw_vessel);
diameter_map = distance_map * 2;
% Extract vessel diameters along skeleton
[y, x] = find(skeleton);
diameters = arrayfun(@(i) diameter_map(y(i), x(i)), 1:length(x));
%% --- Edge Detection for Overlay ---
edge_thresholds = [0.1, 0.4];
edges = edge(frame_enhanced, 'Canny', edge_thresholds);
%% --- Visualization: Frangi + Edges + Skeleton + Diameters ---
figure;
imshow(frame_enhanced, []);
hold on;
contour(edges, [1,1], 'g', 'LineWidth', 1);
plot(x, y, 'r.', 'MarkerSize', 5);
scatter(x, y, 15, diameters, 'filled');
colormap(parula);
c = colorbar;
c.Label.String = 'Diameter (pixels)';
title(['Edges + Skeleton + Diameters (Frame ', num2str(frame_idx), ')']);
%% --- Plot Diameter Profile ---
figure;
plot(1:length(diameters), diameters, 'b.-');
xlabel('Skeleton Point Index');
ylabel('Vessel Diameter (pixels)');
title('Vessel Diameter Profile Along Skeleton');

As you can see, the edges are picked up but not always, and the diameters are calculated on no real basis. They don’t seem to be particularly telling.
My question is:
How can I ensure accurate edge detection that captures the actual vessel boundaries and calculate their diameters?
Accepted Answer
More Answers (0)
Categories
Find more on Biomedical Imaging in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!