MATLAB: Help in measuring diameter of vessel

arteryblood vesseldistance transformimage analysisImage Processing Toolboxvessel

Hello,
I need help in understanding why my code doesn't output quite what I thought it would. I am trying to measure the diameter of a vessel in a 512×512 image by measuring the diameter at several points and averaging the measurements. Here is my code
segmentLength = round(size(image,1)/segments);
[rightrow, rightcol] = find(image==3);
rightwall = [rightcol rightrow];
for j = 1:segmentLength:(size(image,1)-segmentLength)
midpt = j+round(segmentLength/2);
[~, midptcol] = find(image(midpt,:)==2);
if isempty(midptcol)==0
[d, p] = min((rightwall(:,1)-midptcol).^2+(rightwall(:,2)-midpt).^2);
%p is the row index of rightwall containing the nearest point
d = sqrt(d);
diameter = [diameter d];
end
end
I changed the value along the right side of the vessel to be 3 in order to identify what wall is the wall on the right and used 20 for my value of segments. When I graph the points to see what this code has done, the points with shortest distance don't seem to actually be those points (as far as I can tell with my eye) and so are not quite the diameter at that point. Can you help me understand what I am missing? Here is the image where the points on the right don't match up with where I would expect them to:
Thanks! Michael

Best Answer

Michael, try this:
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 = 20;
% Read in mat file.
storedStructure = load('binaryimage.mat');
binaryImage = storedStructure.BWfinal;
% Display the image.



subplot(2, 2, 1);
imshow(binaryImage, []);
title('Original Binary Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
% Get rid of tool bar and pulldown menus that are along top of figure.
set(gcf, 'Toolbar', 'none', 'Menu', 'none');
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
drawnow;
% Fill the image.
binaryImage(1,:) = true;
binaryImage(end,:) = true;
binaryImage = imfill(binaryImage, 'holes');
% Display the image.
subplot(2, 2, 2);
imshow(binaryImage, []);
title('Original Binary Image', 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
% Get the Euclidean Distance Transform.
binaryImage(1,:) = false;
binaryImage(end,:) = false;
edtImage = bwdist(~binaryImage);
% Display the image.
subplot(2, 2, 3);
imshow(edtImage, []);
title('Distance Transform Image', 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
skelImage = bwmorph(binaryImage, 'skel', inf);
skelImage = bwmorph(skelImage, 'spur', 40);
% There should be just one now. Let's check
[labeledImage, numLines] = bwlabel(skelImage);
fprintf('Found %d lines\n', numLines);
% Display the image.
subplot(2, 2, 4);
imshow(skelImage, []);
title('Skeleton Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Measure the radius be looking along the skeleton of the distance transform.
meanRadius = mean(edtImage(skelImage))
meanDiameter = 2 * meanRadius
message = sprintf('Mean Radius = %.1f pixels.\nMean Diameter = %.1f pixels',...
meanRadius, meanDiameter);
uiwait(helpdlg(message));