matlabimage-processing

Find largest vertical distance in rhombus


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:

rhombus image with overlaid horizontal line

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!


Solution

  • 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.