Following similar logic to this answer, we'll use regionprops to get the length and width of the bounding box rectangles. Then we can compute the length:width ratio, set a threshold, and determine which boxes are greater than that threshold. Then you can plot accepted objects with a red rectangle and rejected objects with a yellow rectangle.
See below for a second method.
I = imread('bwimage.png');
BW = imbinarize(rgb2gray(I));
BWConv = bwconvhull(~BW);
BW = BW & BWConv;
stats = regionprops('table',BW,'BoundingBox');
stats.LenWdRatio = stats.BoundingBox(:,3) ./ stats.BoundingBox(:,4);
thresh = 2.0;
stats.isGreater = stats.LenWdRatio > thresh;
figure()
h = imshow(BW);
axis on
hold on
arrayfun(@(i)rectangle('Position',stats.BoundingBox(i,:),'EdgeColor','r'), find(stats.isGreater));
arrayfun(@(i)rectangle('Position',stats.BoundingBox(i,:),'EdgeColor','y'), find(~stats.isGreater));
Second method: using major:minor axis length
Instead of using the horizontal and vertical extent of the bounding box, you could use the ratio of the MajorAxisLength to the MinorAxisLength. Here's an example why this method might be better. Suppose you have an long object that stretchs along a diagonal with slope=1. The width and height of the bounding box will be equal even though it's a very long and narrow object. If you used the ratio of the Major:Minor axis lengths, the object will be detected as long and narrow even through the bounding box is square.
To use this method, make the following changes.
stats = regionprops('table',BW,'BoundingBox','MajorAxisLength','MinorAxisLength');
stats.LenWdRatio = stats.MajorAxisLength ./ stats.MinorAxisLength;
[Update]
I forgot to show how to remove the objects.
When you call regionprop, add the SubarrayIdx property to the list.
stats = regionprops('table',BW,'BoundingBox','MajorAxisLength','MinorAxisLength','SubarrayIdx');
Then you can loop through each rejected object and replace its values in BW with false (black).
objRemoveIdx = find(~stats.isGreater);
for i = find(~stats.isGreater).'
BW(stats.SubarrayIdx{i,1},stats.SubarrayIdx{i,2}) = false;
end
figure()
h = imshow(BW);
axis on
hold on
arrayfun(@(i)rectangle('Position',stats.BoundingBox(i,:),'EdgeColor','r'), find(stats.isGreater));
arrayfun(@(i)rectangle('Position',stats.BoundingBox(i,:),'EdgeColor','y'), find(~stats.isGreater));
Best Answer