MATLAB Answers

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

9 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)

Sign in to answer this question.