# Find boundary pixel coordinates nearest to a line

6 views (last 30 days)
Kamu on 5 May 2017
Edited: DGM on 9 Feb 2023
Given a set of pixels (x, y) from regionprops and the center coordinate (cx, cy). I would like to draw a line at 1 degree from the centroid to the boundary point which is the closest to that line.
My idea was to first calculate the angle from each boundary pixels. The problem is, that I have less boundary pixels in total than degree steps (360).
On the other hand, if I draw the line first, I do not know how to identify the pixel, that intersect with the boundary. The overall goal is to draw lines and store the attached boundary pixel coordinate like:
Any hint would be helpful. Thanks

Yongjie on 8 Feb 2023
Moved: DGM on 8 Feb 2023
Presume all the cells inside the boundary is with value, like 1. all the outside cells are 0.
you can first figure out the line from the center (cx,cy) and with the slope b which is corresponding to 1 degree. then you get a line y = a + bx. choose a distance r which is big enough to pass the boundary. then you know two points (cx,cy) and (x1,y1).
then you can see https://www.mathworks.com/matlabcentral/answers/230155-how-to-determine-which-grid-cells-a-line-segment-passes-through for how to get the cells along this line. the last cell with value 1 is the boundary cell you are looking for

DGM on 9 Feb 2023
Edited: DGM on 9 Feb 2023
Given the illustration and description, it's not quite clear if we're trying to draw a line to the first intersection or not. It's also not really clear whether we're trying to do this in a figure or in an image. As this is a dead question, I choose to assume that we're doing it in an image.
Consider the following image:
Here, I'm just going to draw a bunch of lines all the way through the blob interior.
% a logical image with a solid blob
% get object/image info
imdiag = norm(sz);
% generate lines
angles = 0:15:345;
linemk = false(sz);
for k = 1:numel(angles)
endpt = imdiag*[cosd(angles(k)) sind(angles(k))];
linemk = linemk | brline(sz,S.Centroid + [0 0; endpt]);
end
% trim lines
linemk = linemk & mask;
% combine perimeter with lines
outmk = bwperim(mask) | linemk;
imshow(outmk)
Here, the lines are drawn only to the first point of intersection.
% a logical image with a solid blob
% get object/image info
imdiag = norm(sz);
% generate lines
angles = 0:15:345;
linemk = false(sz);
for k = 1:numel(angles)
endpt = imdiag*[cosd(angles(k)) sind(angles(k))];
linemk = linemk | brline(sz,S.Centroid + [0 0; endpt]);
end
% trim lines
linemk = linemk & mask;
% get rid of line segments that aren't connected to the centroid
linemk = bwselect(linemk,S.Centroid(1),S.Centroid(2));
% combine perimeter with lines
outmk = bwperim(mask) | linemk;
imshow(outmk)
Note that this doesn't necessarily stop when a line contacts the perimeter of the blob. It stops before the line contacts the background. A line may contact the perimeter and continue, so long as it continues within the interior of the blob. Note the line which grazes the perimeter vertex in the lower right.
Whether that's an adequate solution is up to readers to decide. It may depend on whether we consider the boundary curve to be part of the foreground or part of the background. As I created the boundary curve from the perimeter of a blob, I'm assuming that it's part of the foreground.
These examples use brline() and imsize() from MIMT, though similar can be done using drawline() or other tools.