Search code examples
matlabimage-processingedge-detection

How make endpoints of bwboundaries consistent in Matlab?


I have an image with 2 edges

if I then plot the boundary of the edges with the code below:

imshow(I); hold on; [B,L,N] = bwboundaries(I);
for k=1:length(B),
    boundary = B{k};
    BL=size(boundary);
    plot(boundary(1,2), boundary(1,1), '*g','MarkerSize',15);
    for j=1:10:BL(1)
        plot(boundary(j,2), boundary(j,1), '.r','MarkerSize',5);
    end

end

As seen in the image above, the starting point (the green star) for the left edge is at the left side of the image, which is what I expected. However, the starting point for the right edge is towards the middle

Apparently this is because bwboundaries deals with tracing objects in clockwise direction, whereas the 2nd edge needs to be traced counterclockwise for it to begin and end on the right boundary of the image

How can Matlab be able to take the positions from bwboundaries and correctly determine the endpoints for the edge on the right?


Solution

  • Not a complete answer to your problem, but an idea I came up with. You can check all points of a boundary for their "closeness" to an image border, and then find minimum/maximum (x, y) values, that'll describe those "ends" you're interested in.

    B = bwboundaries(img);
    
    % Threshold for "closeness" to an image border.
    thrNear = 5;
    
    for k = 1:numel(B)
    
      b = B{k};
    
      nearTop = b(:, 1) < thrNear;
      nearBottom = b(:, 1) > (size(img, 1) - thrNear);
      nearLeft = b(:, 2) < thrNear;
      nearRight = b(:, 2) > (size(img, 2) - thrNear);
    
      closeToTop = b(nearTop, :)
      closeToBottom = b(nearBottom, :)
      closeToLeft = b(nearLeft, :)
      closeToRight = b(nearRight, :)
    
    end
    

    For example, for the right shape in your original image, you get:

    closeToTop = [](0x2)
    closeToBottom = [](0x2)
    closeToLeft = [](0x2)
    closeToRight =
    
        79   283
        79   284
        79   285
        79   286
        79   287
        80   287
        81   287
        81   286
        81   285
        81   284
        81   283
       215   283
       215   284
       215   285
       215   286
       215   287
       216   287
       217   287
       217   286
       217   285
       217   284
       217   283
    

    Now, go for the maximum x value(s) (287), and find appropriate (non-neighbouring) y values (79-81 vs. 215-217). Repeat that for each image border.

    I hope, you get my idea. To be honest, I don't want to implement that entirely, but don't hesitate to ask, if my description is not precise enough.