How can I "get rid" of certain regions in my segmented image based on their dimensions?

2 次查看(过去 30 天)
Hello everyone. I have a code that takes in a binarized image, segments it, and finds the most common range of width and height of the segments. I would like to now go through the regions and "delete" the regions whose dimensions do not fall within these most common ranges (so turn these segments' pixels from 1 to 0).
The image that I am using for the code is attached, and the code is below. I would appreciate any advice on this!
%%----------Segmentation----------------------------------------------
%img = (incoming image)
% Label each region with 8-connectivity
[labeledImage, numOfBlobs] = bwlabel(img, 8);
% Add pseudo-colors to blobs and create image
pseudoColoredImage = label2rgb (labeledImage, 'hsv', 'k', 'shuffle');
% Display pseudo-colored image
subplot(2, 3, 1);
imshow(pseudoColoredImage);
impixelinfo;
axis('on', 'image');
title('Pseudo-colored Image', 'FontSize', fontSize, 'Interpreter', 'None');
hold on
drawnow;
% Retrieve blob properties
blobProps = regionprops(labeledImage, img, 'Area', 'BoundingBox', 'Centroid');
numOfBlobs = size(blobProps, 1);
% Get bounding boxes
bounds = vertcat(blobProps.BoundingBox); %concatenates matrices together
widths = bounds(:, 3);
heights = bounds(:, 4);
% Get a list of all the dimensions
allWidths = [widths];
allHeights = [heights];
% Calculate mode dimensions
modeWidth = mode(allWidths, 'all');
modeHeight = mode(allHeights, 'all');
% Show the histograms of widths and heights
subplot(2, 3, 2);
histogram(allWidths);
xline(modeWidth, 'Color', 'r', 'LineWidth', 3)
caption = sprintf('Distribution of %d Widths.\nMode Width = %.2f pixels.', numOfBlobs, modeWidth);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
xlabel('Width', 'FontSize', fontSize, 'Interpreter', 'None');
ylabel('Count', 'FontSize', fontSize, 'Interpreter', 'None');
grid on;
drawnow;
subplot(2, 3, 3);
histogram(allHeights);
xline(modeHeight, 'Color', 'r', 'LineWidth', 3)
caption = sprintf('Distribution of %d Heights.\nMode Height = %.2f pixels.', numOfBlobs, modeHeight);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
xlabel('Height', 'FontSize', fontSize, 'Interpreter', 'None');
ylabel('Count', 'FontSize', fontSize, 'Interpreter', 'None');
grid on;
drawnow;
%-------Find the most frequently occurring region of widths and heights
%Divide the widths and heights into bins
[bincountsWidths,edgesW] = histcounts(allWidths);
[bincountsHeights,edgesH] = histcounts(allHeights);
%Find the max value in both, then find the value in edges that has the same
%index plus the next one, and this is the desired range of dimensions.
[maxM, edgeMLower] = max(bincountsWidths);
[maxN, edgeNLower] = max(bincountsHeights);
%Check if the maximum value occurs only once
maxOccurrencesWidth = length(find(bincountsWidths(:)== maxM));
maxOccurrencesHeight = length(find(bincountsHeights(:)== maxN));
if maxOccurrencesWidth == 1
%Occurs once -> take the edges of this bin
edgesMaxOccurrencesW = edgesW(edgeMLower:edgeMLower+1); %#ok<NASGU>
else
%Occurs more than once -> find every occurrence of the max value and find the edges of those bins
a = find(bincountsWidths(:) == maxM);
edgesMaxOccurrencesW=zeros(length(a),2);
for k=1:length(a)
%Create an arrray with as many rows as there are length(a)
%Put the upper and lower edge of each max occurrence in that array
edgesMaxOccurrencesW(k,:) = [edgesW(a(k)), edgesW(a(k)+1)];
end
end
if maxOccurrencesHeight == 1
edgesMaxOccurrencesH = edgesH(edgeNLower:edgesNLower+1); %#ok<NASGU>
else
b = find(bincountsHeights(:) == maxN);
edgesMaxOccurrencesH=zeros(length(b),2);
for k=1:length(b)
edgesMaxOccurrencesH(k,:) = [edgesH(b(k)), edgesH(b(k)+1)];
end
end
% edgesMaxOccurrencesW;
% edgesMaxOccurrencesH;
% --------Remove regions that are not within the "most frequent" range(s)
%Find all widths/heights within the bounds of edgesMaxOccurrences
newAllWidths = zeros(size(allWidths));
newAllHeights = zeros(size(allHeights));
for k = 1:size(edgesMaxOccurencesW, 1)
for j = 1:size(allWidths,1)
for l = 1:size(allWidths,2)
if (allWidths(j,l) > edgesMaxOccurencesW(k,1) && allWidths(j,l) < edgesMaxOccurencesW(k,2));
newAllWidths(j,l) = allWidths(j,l);
newAllHeights(j,l) = allHeights(j,l);
end
end
end
end
for k = 1:size(edgesMaxOccurencesH, 1)
for j = 1:size(allHeights,1)
for l = 1:size(allHeights,2)
if (allHeights(j,l) > edgesMaxOccurencesH(k,1) && allHeights(j,l) < edgesMaxOccurencesH(k,2));
newAllWidths(j,l) = allWidths(j,l);
newAllHeights(j,l) = allHeights(j,l);
end
end
end
end
%Now I want to find all the regions within the image that do not meet these
%dimension criteria and "delete" them

采纳的回答

Benjamin Thompson
>> int32(blobProps(130).BoundingBox)
ans =
1×4 int32 row vector
2521 1795 72 32
The bounding box defines the left, top, width, height for a region. The origin (1, 1, ) is at the top left. The image is just a matrix, so
labeledImage((1795:(1795+32)),(2521:(2521+72))) = 0;
Remember to use row indices first in the matrix assignment (y value), then the column indices (x value).

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Images 的更多信息

产品


版本

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by