Inertia axes in an image

9 views (last 30 days)
Mattia Di Luca
Mattia Di Luca on 26 Nov 2018
Commented: TED MOSBY on 26 Aug 2024
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

Answers (2)

TED MOSBY
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:
Hope this answers your query.
  1 Comment
Walter Roberson
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

Sign in to comment.


Walter Roberson
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
s = struct with fields:
Centroid: [402.5769 292.0295] MajorAxisLength: 452.7540 MinorAxisLength: 384.6438 Orientation: 45
M = makehgtform("zrotate", deg2rad(s.Orientation))
M = 4x4
0.7071 -0.7071 0 0 0.7071 0.7071 0 0 0 0 1.0000 0 0 0 0 1.0000
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
maj1 = [s.MajorAxisLength/2,zeros(1,3)]
maj1 = 1x4
226.3770 0 0 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
maj2 = -maj1
maj2 = 1x4
-226.3770 0 0 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
min1 = [0,s.MinorAxisLength/2,zeros(1,2)]
min1 = 1x4
0 192.3219 0 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
min2 = -min1
min2 = 1x4
0 -192.3219 0 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
P = [maj1; maj2; min1; min2] * M
P = 4x4
160.0727 -160.0727 0 0 -160.0727 160.0727 0 0 135.9921 135.9921 0 0 -135.9921 -135.9921 0 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
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
  1 Comment
TED MOSBY
TED MOSBY on 26 Aug 2024
yeah thats just another way to do it :)

Sign in to comment.

Categories

Find more on Graphics 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!