Inertia axes in an image
9 views (last 30 days)
Show older comments
I have to evaluate the symmetry of this nevus, you can see his binary image.
I have found the centroid, would you give me an advise for the code to find and show the inertia axis of the image which match each other in the centroid?
I would have to align them with x and y axis of the image with a rotation then.
Thank you
0 Comments
Answers (2)
TED MOSBY
on 25 Aug 2024
Edited: TED MOSBY
on 25 Aug 2024
To plot the inertia axis using the centroid you can calculate the principal axis of inertia. These axes can be determined from the image's covariance matrix, and they provide a way to understand the orientation and elongation of the shape.
You can then use eigenvalue decomposition on the covariance matrix to find the principal axes. Have a look at the code below:
% Load your binary image
image = imread('Cattura.jpg'); % Replace with your image file
if size(image, 3) == 3
image = rgb2gray(image); % Convert to grayscale if necessary
end
binaryImage = imbinarize(image);
% Find coordinates of white pixels
[y_indices, x_indices] = find(binaryImage);
% Calculate the centroid
centroid_x = mean(x_indices);
centroid_y = mean(y_indices);
% Center the coordinates
x_centered = x_indices - centroid_x;
y_centered = y_indices - centroid_y;
% Create the covariance matrix
cov_matrix = cov(x_centered, y_centered);
% Calculate eigenvalues and eigenvectors
[eigenvectors, eigenvalues] = eig(cov_matrix);
% Sort eigenvectors by eigenvalues in descending order
[~, order] = sort(diag(eigenvalues), 'descend');
eigenvectors = eigenvectors(:, order);
eigenvalues = diag(eigenvalues);
eigenvalues = eigenvalues(order);
% Plot the image and the principal axes
figure;
imshow(binaryImage);
hold on;
plot(centroid_x, centroid_y, 'ro', 'MarkerSize', 10, 'LineWidth', 2);
% Draw the principal axes with lengths proportional to the square root of eigenvalues
colors = ['r', 'g']; % Define colors as a character array
for i = 1:2
vector = eigenvectors(:, i);
quiver(centroid_x, centroid_y, sqrt(eigenvalues(i)) * vector(1), sqrt(eigenvalues(i)) * vector(2), ...
'Color', colors(i), 'LineWidth', 2, 'MaxHeadSize', 2);
end
title('Inertia Axes of Nevus');
hold off;
% Optional: Rotate the image to align the principal axis with the x-axis
angle = atan2(eigenvectors(2, 1), eigenvectors(1, 1));
angle_degrees = rad2deg(angle);
rotated_image = imrotate(binaryImage, -angle_degrees, 'bilinear', 'crop');
% Show rotated image
figure;
imshow(rotated_image);
title('Rotated Image');
Here is the output of the above code in MATLAB R2023b:
For further information refer to the following documentation:
Eigenvalues: www.mathworks.com/help/matlab/math/eigenvalues.html?searchHighlight=eigenvalues&s_tid=srchtitle_support_results_1_eigenvalues
Hope this answers your query.
1 Comment
Walter Roberson
on 25 Aug 2024
I think in theory you should be able to just use regionprops centroid, majoraxislength, minoraxeslength, and orientation. However I seem to be having difficulty getting the plotting to work correctly
Walter Roberson
on 25 Aug 2024
% Load your binary image
image = imread('Cattura.JPG'); % Replace with your image file
if size(image, 3) == 3
image = rgb2gray(image); % Convert to grayscale if necessary
end
binaryImage = imbinarize(image);
s = regionprops(binaryImage, ["MajorAxisLength", "MinorAxisLength", "Orientation", "Centroid"]);
s.Orientation = 45
M = makehgtform("zrotate", deg2rad(s.Orientation))
maj1 = [s.MajorAxisLength/2,zeros(1,3)]
maj2 = -maj1
min1 = [0,s.MinorAxisLength/2,zeros(1,2)]
min2 = -min1
P = [maj1; maj2; min1; min2] * M
h = imagesc(binaryImage);
hold on
plot(P(1:2,1) + s.Centroid(1), P(1:2,2) + s.Centroid(2), 'displayname', 'major')
plot(P(3:4,1) + s.Centroid(1), P(3:4,2) + s.Centroid(2), 'displayname', 'minor');
legend show
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!