clc;
close all;
clear;
workspace;
format long g;
format compact;
fontSize = 20;
folder = pwd;
baseFileName = 'tail.png';
fullFileName = fullfile(folder, baseFileName);
if ~exist(fullFileName, 'file')
fullFileNameOnSearchPath = baseFileName;
if ~exist(fullFileNameOnSearchPath, 'file')
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
rgbImage = imread(fullFileName);
subplot(2, 3, 1);
imshow(rgbImage, []);
title('Original Image', 'FontSize', fontSize, 'Interpreter', 'None');
axis('on', 'image');
hp = impixelinfo();
[rows, columns, numberOfColorChannels] = size(rgbImage)
if numberOfColorChannels > 1
grayImage = rgbImage(:, :, 2);
else
grayImage = rgbImage;
end
subplot(2, 3, 1);
imshow(rgbImage, []);
title('Original Image', 'FontSize', fontSize, 'Interpreter', 'None');
axis('on', 'image');
hp = impixelinfo();
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0, 0.04, 1, 0.96]);
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
drawnow;
binaryImage = grayImage ~= 255;
binaryImage = imfill(binaryImage, 'holes');
binaryImage = bwareafilt(binaryImage, 1);
subplot(2, 3, 2);
imshow(binaryImage, []);
title('Initial Binary Image', 'FontSize', fontSize, 'Interpreter', 'None');
axis('on', 'image');
hp = impixelinfo();
drawnow;
regionWidth = zeros(rows, 1);
for row = 1 : rows
thisWidth = find(binaryImage(row, :), 1, 'last') - find(binaryImage(row, :), 1, 'first');
if ~isempty(thisWidth)
regionWidth(row) = thisWidth;
end
end
subplot(2, 3, [3,6]);
plot(regionWidth, 'b-', 'LineWidth', 2);
grid on;
title('Region Width vs. line down the image', 'FontSize', fontSize);
xlabel('Row', 'FontSize', fontSize);
ylabel('Width in pixels', 'FontSize', fontSize);
minWidth = 20;
binaryImage(regionWidth < minWidth, :) = false;
subplot(2, 3, 4);
imshow(binaryImage, []);
title('Final Binary Image', 'FontSize', fontSize, 'Interpreter', 'None');
axis('on', 'image');
hp = impixelinfo();
drawnow;
props = regionprops(binaryImage, 'MajorAxisLength', 'MinorAxisLength', 'Orientation', 'Centroid', 'Perimeter')
xCenter = props.Centroid(1);
yCenter = props.Centroid(2);
xRadius = props.MinorAxisLength / 2;
yRadius = props.MajorAxisLength / 2;
theta = linspace(0, 2*pi, ceil(props.Perimeter));
x = xRadius * cos(theta) + xCenter;
y = yRadius * sin(theta) + yCenter;
angleInDegrees = props.Orientation - 90;
rotationMatrix = [cosd(angleInDegrees), -sind(angleInDegrees); sind(angleInDegrees), cosd(angleInDegrees)];
xy = [x', y'];
xyRotated = xy * rotationMatrix;
x = xyRotated(:, 1);
y = xyRotated(:, 2);
subplot(2, 3, 5);
imshow(rgbImage, []);
title('Image with Fitted Ellipse', 'FontSize', fontSize, 'Interpreter', 'None');
axis('on', 'image');
hold on;
plot(x, y, 'r-', 'LineWidth', 2);
plot(xCenter, yCenter, 'r+', 'LineWidth', 2, 'MarkerSize', 13);
axis('image', 'on');
grid on;
fprintf('X Center = column #%.1f\n', xCenter);
fprintf('Y Center = row #%.1f\n', yCenter);
fprintf('Minor Axis Length = %.1f\n', xRadius);
fprintf('Major Axis Length = %.1f\n', yRadius);
fprintf('Orientation = %.1f degrees\n', angleInDegrees);
uiwait(helpdlg('Done!'));
Best Answer