%% Identifying Border-Touching Objects Using imclearborder or regionprops
% I have seen some requests and questions related to identifying objects in a binary image that are touching the image border. Sometimes the question relates to the use of imclearborder, and sometimes the question is about regionprops. Today, I'll show you how to tackle the problem both ways.
%% Using imclearborder
% I'll be using this binary version of the rice.png sample image from the Image Processing Toolbox.

url = "https://blogs.mathworks.com/steve/files/rice-bw-1.png";
A = imread(url);
imshow(A)

%
% The function imclearborder removes all objects touching the border.

B = imclearborder(A);
imshow(B)

%
% That seems to be the opposite of what we want. We can, however, convert this into the desired result by using the MATLAB element-wise logical operators, such as & (and), | (or), and ~ (not). In words, we want the foreground pixels that are in A and are not in B. As a MATLAB expression, it looks like this:

C = A & ~B;
imshow(C)

%
%% Using regionprops
% The function regionprops can compute all sorts of properties of binary image objects. Here is a simple example that computes the area and centroid of each object in our sample image. I'm using the form of regionprops that returns a table.

props = regionprops("table",A,["Area" "Centroid"])

%
% My technique for finding border-touching objects with regionprops uses the BoundingBox property, so include that property along with any other properties that you want to measure.

props = regionprops("table",A,["Area" "Centroid" "BoundingBox"])

% For any particular object, BoundingBox is a four-element vector containing the left, top, width, and height of the bounding box. For example, here is the bounding box of the 20th object:

props.BoundingBox(20,:)

%
% By comparing these values to the size of the image, we can identify which objects touch the image border.
% Start by determining the objects that touch specific borders.

left_coordinate = props.BoundingBox(:,1);
props.TouchesLeftBorder = (left_coordinate == 0.5);
top_coordinate = props.BoundingBox(:,2);
props.TouchesTopBorder = (top_coordinate == 0.5);
right_coordinate = left_coordinate + props.BoundingBox(:,3);
bottom_coordinate = top_coordinate + props.BoundingBox(:,4);
[M,N] = size(A);
props.TouchesRightBorder = (right_coordinate == (N+0.5));
props.TouchesBottomBorder = (bottom_coordinate == (M+0.5))

%
% Finally, compute whether objects touch any border using |, the element-wise OR operator.

props.TouchesAnyBorder = props.TouchesLeftBorder | ...
    props.TouchesTopBorder | ...
    props.TouchesRightBorder | ...
    props.TouchesBottomBorder

%
% I'll finish with a quick visual sanity check of the results.

L = bwlabel(A);
L_touches_border = ismember(L,find(props.TouchesAnyBorder));
imshowpair(A,L_touches_border)