Inertia axes in an image

6 visualizzazioni (ultimi 30 giorni)
Mattia Di Luca
Mattia Di Luca il 26 Nov 2018
Commentato: TED MOSBY il 26 Ago 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

Risposte (2)

TED MOSBY
TED MOSBY il 25 Ago 2024
Modificato: TED MOSBY il 25 Ago 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 Commento
Walter Roberson
Walter Roberson il 25 Ago 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

Accedi per commentare.


Walter Roberson
Walter Roberson il 25 Ago 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 Commento
TED MOSBY
TED MOSBY il 26 Ago 2024
yeah thats just another way to do it :)

Accedi per commentare.

Categorie

Scopri di più su Graphics in Help Center e File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by