1

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?

user5739619
  • 1,748
  • 5
  • 26
  • 40
  • 1
    The start point is simply the first pixel encountered when traversing the image in column-major order. – Cris Luengo Mar 07 '19 at 23:50
  • I think you are confusing boundaries (the edge of an object) with lines (1D structures). https://stackoverflow.com/questions/50359485/what-is-the-difference-between-a-line-and-an-edge-in-image-detection/50359884#50359884 . Also, please edit your question instead of adding information in comments. These comments are not meant to last. There is no point in having a long discussion here. Edit your question to clarify and improve it. – Cris Luengo Mar 08 '19 at 00:56
  • 1
    I think you need an entirely new algorithm all together. You shouldn't be using `bwboundaries` here and Cris already mentioned how it works. I would suggest perhaps skeletonizing each shape, then looking for end points - basically, any points that only have a 1 connected neighbour in a local 3 x 3 neighbourhood. That can be performed by using a convolution with a 3 x 3 `ones` kernel with a 0 in the middle and finding spots that only output the value of 1. – rayryeng Mar 08 '19 at 03:34

1 Answers1

0

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.

HansHirse
  • 18,010
  • 10
  • 38
  • 67