MATLAB Answers

How can I calculated centroid contour distance in image at every 10 degree?

6 views (last 30 days)
I I have done many experiments, but I have not been able to determine the angle in the image, I want to get the vertices only at every 10 degrees, but in my experiments, I get the vertices on each pixel contained in the image? please help me solve this problem :). Here is my code
clc;
close all;
clear all;
fontSize = 10;
image_folder = 'D:\Mangrove Classification\Data Training';
filenames = dir(fullfile(image_folder, '*.png'));
total_images = numel(filenames);
for n = 1:total_images
full_name= fullfile(image_folder, filenames(n).name);
I = imread(full_name);
I = imresize(I,0.2);
M = I(:,:,1) < 168;
% Fill holes
M = imfill(M, 'holes');
% Take largest blob only.
M = bwareafilt(M, 1);
subplot (1,2,1);
imshow(M);
[labeledImage numberOfBlobs] = bwlabel(M, 8);
blobMeasurements = regionprops(labeledImage, 'Centroid', 'Orientation');
xCenter = blobMeasurements(1).Centroid(1);
yCenter = blobMeasurements(1).Centroid(2);
subplot(1,2,2);
imshow(I);
axis on;
hold on;
% Plot the centroid.
plot(xCenter, yCenter, 'b+', 'MarkerSize', 10, 'LineWidth', 3);
boundaries = bwboundaries(M);
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
for k = 1 : length(boundaries)
thisBoundary = boundaries{k};
plot(thisBoundary(:,2), thisBoundary(:,1), 'b', 'LineWidth', 2);
numberOfBoundaryPoints = length(thisBoundary);
angle = 0: 10 : 360;
for a = 1 : length(angle)
xb = thisBoundary(a,2);
yb = thisBoundary(a,1);
angles(a) = atand((yb-yCenter) / (xb-xCenter));
distances(a) = sqrt((xb-xCenter).^2+(yb-yCenter).^2);
end
end
save('Latih.mat','angles','distances');
end

  4 Comments

Show 1 older comment
Muhammad Andi Yusran
Muhammad Andi Yusran on 13 Dec 2019
hello darova, yeah u right, the code get all of the boundary points in every pixels as i know (CMIIW), but in my case, i just want to declare the image as 360 degree and get the boundary point every 10 degree, please help me :(

Sign in to comment.

Accepted Answer

Image Analyst
Image Analyst on 13 Dec 2019
No, that won't work (as you know). Try it this way, in my well-commented/explained example below:
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;
image_folder = pwd; %'D:\Mangrove Classification\Data Training';
filenames = dir(fullfile(image_folder, '*.jpg'));
totalNumberOfImages = numel(filenames);
% Define the angles where we want to get distances for.
desiredAngles = 0: 20 : 360;
% Define the output distance matrix.
allDistances = zeros(totalNumberOfImages, length(desiredAngles));
for k = 1:totalNumberOfImages
fullImageFileName= fullfile(image_folder, filenames(k).name);
grayImage = imread(fullImageFileName);
subplot (2,2,1);
imshow(grayImage);
axis('on', 'image');
caption = sprintf('Original image : "%s"', filenames(k).name);
title(caption, 'FontSize', fontSize);
if ndims(grayImage) == 3
% It's not gray scale. convert to gray scale.
grayImage = rgb2gray(grayImage);
end
% Resize to one fifth the original size.
grayImage = imresize(grayImage,0.2);
% Get a binary image.
% Threshold to get things darker than 168 gray levels.
binaryImage = grayImage(:,:,1) < 168;
% Fill holes
binaryImage = imfill(binaryImage, 'holes');
% Take largest blob only.
binaryImage = bwareafilt(binaryImage, 1);
subplot (2,2,2);
imshow(binaryImage);
axis('on', 'image');
title('Binary Image', 'FontSize', fontSize);
% Find the centroid.
[labeledImage, numberOfBlobs] = bwlabel(binaryImage, 8);
blobMeasurements = regionprops(labeledImage, 'Centroid');
xCenter = blobMeasurements(1).Centroid(1);
yCenter = blobMeasurements(1).Centroid(2);
% Plot the centroid over the image
subplot(2,2,3);
cla reset;
imshow(grayImage);
title('Resized Gray Image with Boundaries Overlaid on It', 'FontSize', fontSize);
axis('on', 'image');
hold on;
% Plot the centroid.
plot(xCenter, yCenter, 'b+', 'MarkerSize', 10, 'LineWidth', 3);
hold off;
% Compute the boundary for this one binary blob.
boundaries = bwboundaries(binaryImage);
% Plot it over the resized gray scale image.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% For this one largest blob in the image, get the distances at certain angles.
thisBoundary = boundaries{1}; % Extract double matrix from cell.
xb = thisBoundary(:,2);
yb = thisBoundary(:,1);
hold on;
plot(xb, yb, '-', 'LineWidth', 2);
grid on;
% Get the distances from every boundary point to the blob centroid.
distances = sqrt((xb-xCenter).^2+(yb-yCenter).^2);
% Get the angles from every boundary point to the blob centroid.
angles = atan2d((yb-yCenter), (xb-xCenter)) + 180;
% depending on the shape, like if the curve bends around,
% there may be more than 1 index with the same angle.
% In that case, just take one of them
% (not sure if it will be the closest or farthest distance though!)
[uniqueAngles, ia, ic] = unique(angles);
% Now get the distances for only the unique angles.
uniqueDistances = distances(ia);
% Now if the angles don't go the whole distance, (like in my image they go from 13.1 to 358.3)
% then we don't know what it will be at 0 or 360 so we need to add on extra points on the ends
uniqueAngles = [uniqueAngles(end)-360; uniqueAngles; uniqueAngles(1) + 360];
uniqueDistances = [uniqueDistances(end); uniqueDistances; uniqueDistances(1)];
% Plot the unique distances vs. angle.
subplot(2, 2, 4);
plot(uniqueAngles, uniqueDistances, 'b.-', 'MarkerSize', 20, 'LineWidth', 2);
grid on;
% Now use interp1() to interpolate the distances at the desired angles
desiredDistances = interp1(uniqueAngles, uniqueDistances, desiredAngles);
% Plot them with red circles.
hold on
plot(desiredAngles, desiredDistances, 'ro', 'LineWidth', 2);
title('Centroid-to-Boundary Distance vs. Angle', 'FontSize', fontSize);
xlabel('Angle [degrees]', 'FontSize', fontSize);
ylabel('Distance [pixels]', 'FontSize', fontSize);
hold off;
drawnow;
% Save these distances in our main output matrix
allDistances(k, :) = desiredDistances;
% See if user wants to quit.
promptMessage = sprintf('Do you want to Continue processing,\nor Quit processing?');
titleBarCaption = 'Continue?';
buttonText = questdlg(promptMessage, titleBarCaption, 'Continue', 'Quit', 'Continue');
if contains(buttonText, 'Quit')
% Crop out only what we've computed so far, discarding the rest of the array which will be all zeros.
allDistances = allDistances(1:k, :);
break; % out of loop.
end
end
save('Latih.mat', 'desiredAngles', 'allDistances');
% delete('Latih.mat');
0000 Screenshot.png

  1 Comment

Muhammad Andi Yusran
Muhammad Andi Yusran on 13 Dec 2019
Ohh yess. Thats work! Thank you so much Mr. Image Analyst. I will try it in my case.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!

Translated by