I have the following problem: I extracted a rhombus out of an image and converted it to a binary image. Within that rhombus I need to find the largest vertical distance.
With my current code I can detect the largest distance (shown in red), no matter what the direction is:
But I am only interested in the largest distance between the upper and the lower corner points of the rhombus (so imagine the red line is rotated by ~ 90 degrees), which is the second largest distance.
My code is the following (which is inspired by this post: Find maximum Euclidean distance of Canny edge output and drawing a line between the points)
clc; clear all;
im = imread('picture');
sharp = imsharpen(im);
grayImage1 = im2gray(sharp);
BinaryImage1 = imbinarize(grayImage1, 0.7);
imshow(BinaryImage1);
title('Extract rhombus');
[posX1, posY1, P1] = impixel;
Rhombus1 = bwselect(BinaryImage1, posX1, posY1);
BW1 = edge(Rhombus1,'Canny',0.8);
hold on;
[ y, x] = find( BW1);
points = [ x y];
[d,idx] = pdist2( points, points, 'euclidean', 'Largest', 1);
idx1 = idx( d==max(d));
[~,idx2] = find(d==max( d));
p={};
for i=1:length(idx1)
p{end+1} = [ points(idx1(i),1), points(idx1(i),2), points(idx2(i),1), points(idx2(i),2)];
end
figure;
imshow(BW1);
hold on;
for i=1:numel(p)
line( [ p{i}(1), p{i}(3)], [p{i}(2), p{i}(4)]);
hdl = get(gca,'Children');
set( hdl(1),'LineWidth',2);
set( hdl(1),'color',[1 0 0]);
end
hold off;
tmp = p{1,1};
dx = tmp(1,1) - tmp(1,3);
dy = tmp(1,2) - tmp(1,4);
Distance = sqrt((tmp(1,3)-tmp(1,1))^2+(tmp(1,4)-tmp(1,2))^2)
Clicking the points manually is no alternative here, I need it to be automated.
I really appreciate your help!
To find the largest vertical distance within the rhombus, you will need to specifically focus on y coordinates of the points rather than the overall Euclidean distance. I modified your code to fix this:
clc;
clear all;
im = imread('picture');
sharp = imsharpen(im);
grayImage1 = im2gray(sharp);
BinaryImage1 = imbinarize(grayImage1, 0.7);
imshow(BinaryImage1);
title('Extract rhombus');
[posX1, posY1, P1] = impixel; % You can remove or skip this part if not needed
Rhombus1 = bwselect(BinaryImage1, posX1, posY1);
BW1 = edge(Rhombus1,'Canny',0.8);
hold on;
% Find the edge points of the rhombus
[y, x] = find(BW1);
% Find the uppermost and lowermost points based on y-coordinate
[minY, minIdx] = min(y);
[maxY, maxIdx] = max(y);
% Calculate the largest vertical distance
verticalDistance = maxY - minY;
% Plot the vertical line between the uppermost and lowermost points
figure;
imshow(BW1);
hold on;
line([x(minIdx), x(maxIdx)], [minY, maxY], 'Color', 'r', 'LineWidth', 2);
hold off;
% Display the distance
fprintf('Largest Vertical Distance: %.2f pixels\n', verticalDistance);
find(BW1)
gives you the coordinates of the edge points. min(y)
and max(y)
identify your y coordinates within the rhombus. The difference between max(y)
and min(y)
gives vertical distance.
This code should find and display the largest vertical distance within the rhombus, its not pretty and is death by powerpoint but should get the job done.