Steve on Image Processing with MATLAB

Image processing concepts, algorithms, and MATLAB

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 可以计算各种属性的二进制图像放大e 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 ,回报ns a table.
props = regionprops("table",A,["Area" "Centroid"])
t = 97×2 table
Area Centroid
1 138 5.9855 35.0870
2 121 6.4463 62.0579
3 67 2.1045 85.1940
4 178 4.5056 117.5674
5 157 9.4650 141.2675
6 286 11.8007 168.5350
7 195 12.0872 205.2974
8 135 9.4296 223.0296
9 176 21.3693 95.9716
10 208 24.1971 26.3125
11 199 28.1859 48.2563
12 188 22.1011 122.6011
13 216 28.2778 179.4630
14 143 28.3427 251.9720
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,[“边界框(“重心”“面积大小)])
t = 97×3 table
Area Centroid BoundingBox
1 138 5.9855 35.0870 0.5000 22.5000 13 22
2 121 6.4463 62.0579 0.5000 53.5000 13 16
3 67 2.1045 85.1940 0.5000 73.5000 4 23
4 178 4.5056 117.5674 0.5000 102.5000 10 28
5 157 9.4650 141.2675 0.5000 132.5000 20 16
6 286 11.8007 168.5350 0.5000 152.5000 26 33
7 195 12.0872 205.2974 0.5000 199.5000 24 12
8 135 9.4296 223.0296 0.5000 218.5000 20 10
9 176 21.3693 95.9716 9.5000 86.5000 25 17
10 208 24.1971 26.3125 10.5000 18.5000 26 16
11 199 28.1859 48.2563 17.5000 37.5000 19 23
12 188 22.1011 122.6011 17.5000 108.5000 10 29
13 216 28.2778 179.4630 17.5000 166.5000 20 24
14 143 28.3427 251.9720 18.5000 245.5000 23 11
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,:)
ans = 1×4
35.5000 113.5000 9.0000 28.0000
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))
t = 97×7 table
Area Centroid BoundingBox TouchesLeftBorder TouchesTopBorder TouchesRightBorder TouchesBottomBorder
1 138 5.9855 35.0870 0.5000 22.5000 13 22 1 0 0 0
2 121 6.4463 62.0579 0.5000 53.5000 13 16 1 0 0 0
3 67 2.1045 85.1940 0.5000 73.5000 4 23 1 0 0 0
4 178 4.5056 117.5674 0.5000 102.5000 10 28 1 0 0 0
5 157 9.4650 141.2675 0.5000 132.5000 20 16 1 0 0 0
6 286 11.8007 168.5350 0.5000 152.5000 26 33 1 0 0 0
7 195 12.0872 205.2974 0.5000 199.5000 24 12 1 0 0 0
8 135 9.4296 223.0296 0.5000 218.5000 20 10 1 0 0 0
9 176 21.3693 95.9716 9.5000 86.5000 25 17 0 0 0 0
10 208 24.1971 26.3125 10.5000 18.5000 26 16 0 0 0 0
11 199 28.1859 48.2563 17.5000 37.5000 19 23 0 0 0 0
12 188 22.1011 122.6011 17.5000 108.5000 10 29 0 0 0 0
13 216 28.2778 179.4630 17.5000 166.5000 20 24 0 0 0 0
14 143 28.3427 251.9720 18.5000 245.5000 23 11 0 0 0 1
Finally, compute whether objects touch any border using | , the element-wise OR operator.
props.TouchesAnyBorder = props.TouchesLeftBorder |...
props.TouchesTopBorder |...
props.TouchesRightBorder |...
props.TouchesBottomBorder
t = 97×8 table
Area Centroid BoundingBox TouchesLeftBorder TouchesTopBorder TouchesRightBorder TouchesBottomBorder TouchesAnyBorder
1 138 5.9855 35.0870 0.5000 22.5000 13 22 1 0 0 0 1
2 121 6.4463 62.0579 0.5000 53.5000 13 16 1 0 0 0 1
3 67 2.1045 85.1940 0.5000 73.5000 4 23 1 0 0 0 1
4 178 4.5056 117.5674 0.5000 102.5000 10 28 1 0 0 0 1
5 157 9.4650 141.2675 0.5000 132.5000 20 16 1 0 0 0 1
6 286 11.8007 168.5350 0.5000 152.5000 26 33 1 0 0 0 1
7 195 12.0872 205.2974 0.5000 199.5000 24 12 1 0 0 0 1
8 135 9.4296 223.0296 0.5000 218.5000 20 10 1 0 0 0 1
9 176 21.3693 95.9716 9.5000 86.5000 25 17 0 0 0 0 0
10 208 24.1971 26.3125 10.5000 18.5000 26 16 0 0 0 0 0
11 199 28.1859 48.2563 17.5000 37.5000 19 23 0 0 0 0 0
12 188 22.1011 122.6011 17.5000 108.5000 10 29 0 0 0 0 0
13 216 28.2778 179.4630 17.5000 166.5000 20 24 0 0 0 0 0
14 143 28.3427 251.9720 18.5000 245.5000 23 11 0 0 0 1 1
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)
|
  • print
  • send email

コメント

コメントを残すには、ここをクリックして MathWorks アカウントにサインインするか新しい MathWorks アカウントを作成します。