How to merge multiple bounding box into one?
Show older comments
How do I merge multiple bounding on the same object as one bounding box around the object? Below is an example. Thanks

Answers (3)
Walter Roberson
on 27 Jan 2016
Edited: Image Analyst
on 27 Jan 2016
Convert the [x y width height] coordinates to start and end coordinates,
[x y x+width-1 y+height-1]
Now take the minimum of all of the left x over all of the boxes to get the left bound, the maximum over all of the right x to get the right bound, the minimum over the top y to get the lower bound, the maximum over the bottom y to get the upper bound.
Nibir Sarker
on 13 Dec 2018
0 votes
Please Provide me the full code for multiple bounding box converting into one bounding box.In the below figure i want to merge trash and human bounding box together then count the object and detect human and trash together.

4 Comments
Walter Roberson
on 17 Dec 2018
I already gave the algorithm above. If you encounter errors with your implementation, then post your code and we will examine it.
Saketh Nannaka
on 17 Apr 2019
colorImage = imread('TEST1.jpg');
figure
imshow(colorImage)
title("sample i/p")
I = rgb2gray(colorImage);
% Detect MSER regions.
[mserRegions, mserConnComp] = detectMSERFeatures(I, ...
'RegionAreaRange',[200 8000],'ThresholdDelta',4);
figure
imshow(I)
hold on
plot(mserRegions, 'showPixelList', true,'showEllipses',false)
title('MSER regions')
hold off
% Use regionprops to measure MSER properties
mserStats = regionprops(mserConnComp, 'BoundingBox', 'Eccentricity', ...
'Solidity', 'Extent', 'Euler', 'Image');
% Compute the aspect ratio using bounding box data.
bbox = vertcat(mserStats.BoundingBox);
w = bbox(:,3);
h = bbox(:,4);
aspectRatio = w./h;
% Threshold the data to determine which regions to remove. These thresholds
% may need to be tuned for other images.
filterIdx = aspectRatio' > 3;
filterIdx = filterIdx | [mserStats.Eccentricity] > .995 ;
filterIdx = filterIdx | [mserStats.Solidity] < .3;
filterIdx = filterIdx | [mserStats.Extent] < 0.2 | [mserStats.Extent] > 0.9;
filterIdx = filterIdx | [mserStats.EulerNumber] < -4;
% Remove regions
mserStats(filterIdx) = [];
mserRegions(filterIdx) = [];
% Show remaining regions
figure
imshow(I)
hold on
plot(mserRegions, 'showPixelList', true,'showEllipses',false)
title('After Removing Non-Text Regions Based On Geometric Properties')
hold off
% Get a binary image of the a region, and pad it to avoid boundary effects
% during the stroke width computation.
regionImage = mserStats(6).Image;
regionImage = padarray(regionImage, [1 1]);
% Compute the stroke width image.
distanceImage = bwdist(~regionImage);
skeletonImage = bwmorph(regionImage, 'thin', inf);
strokeWidthImage = distanceImage;
strokeWidthImage(~skeletonImage) = 0;
% Show the region image alongside the stroke width image.
figure
subplot(1,2,1)
imagesc(regionImage)
title('Region Image')
subplot(1,2,2)
imagesc(strokeWidthImage)
title('Stroke Width Image')
% Compute the stroke width variation metric
strokeWidthValues = distanceImage(skeletonImage);
strokeWidthMetric = std(strokeWidthValues)/mean(strokeWidthValues);
% Threshold the stroke width variation metric
strokeWidthThreshold = 0.4;
strokeWidthFilterIdx = strokeWidthMetric > strokeWidthThreshold;
% Process the remaining regions
for j = 1:numel(mserStats)
regionImage = mserStats(j).Image;
regionImage = padarray(regionImage, [1 1], 0);
distanceImage = bwdist(~regionImage);
skeletonImage = bwmorph(regionImage, 'thin', inf);
strokeWidthValues = distanceImage(skeletonImage);
strokeWidthMetric = std(strokeWidthValues)/mean(strokeWidthValues);
strokeWidthFilterIdx(j) = strokeWidthMetric > strokeWidthThreshold;
end
% Remove regions based on the stroke width variation
mserRegions(strokeWidthFilterIdx) = [];
mserStats(strokeWidthFilterIdx) = [];
% Show remaining regions
figure
imshow(I)
hold on
plot(mserRegions, 'showPixelList', true,'showEllipses',false)
title('After Removing Non-Text Regions Based On Stroke Width Variation')
hold off
%Get bounding boxes for all the regions
bboxes = vertcat(mserStats.BoundingBox);
% Convert from the [x y width height] bounding box format to the [xmin ymin
% xmax ymax] format for convenience.
xmin = bboxes(:,1);
ymin = bboxes(:,2);
xmax = xmin + bboxes(:,3) - 1;
ymax = ymin + bboxes(:,4) - 1;
% Expand the bounding boxes by a small amount.
expansionAmount = 0.02;
xmin = (1-expansionAmount) * xmin;
ymin = (1-expansionAmount) * ymin;
xmax = (1+expansionAmount) * xmax;
ymax = (1+expansionAmount) * ymax;
% Clip the bounding boxes to be within the image bounds
xmin = max(xmin, 1);
ymin = max(ymin, 1);
xmax = min(xmax, size(I,2));
ymax = min(ymax, size(I,1));
% Show the expanded bounding boxes
expandedBBoxes = [xmin ymin xmax-xmin+1 ymax-ymin+1];
IExpandedBBoxes = insertShape(colorImage,'Rectangle',expandedBBoxes,'LineWidth',3);
figure
imshow(IExpandedBBoxes)
title('Expanded Bounding Boxes Text')
% Compute the overlap ratio
overlapRatio = bboxOverlapRatio(expandedBBoxes, expandedBBoxes);
% Set the overlap ratio between a bounding box and itself to zero to
% simplify the graph representation.
n = size(overlapRatio,1);
overlapRatio(1:n+1:n^2) = 0;
% Create the graph
g = graph(overlapRatio);
% Find the connected text regions within the graph
componentIndices = conncomp(g);
% Compute the overlap ratio
overlapRatio = bboxOverlapRatio(expandedBBoxes, expandedBBoxes);
% Set the overlap ratio between a bounding box and itself to zero to
% simplify the graph representation.
n = size(overlapRatio,1);
overlapRatio(1:n+1:n^2) = 0;
% Create the graph
g = graph(overlapRatio);
% Find the connected text regions within the graph
componentIndices = conncomp(g);
% Merge the boxes based on the minimum and maximum dimensions.
xmin = accumarray(componentIndices', xmin, [], @min);
ymin = accumarray(componentIndices', ymin, [], @min);
xmax = accumarray(componentIndices', xmax, [], @max);
ymax = accumarray(componentIndices', ymax, [], @max);
% Compose the merged bounding boxes using the [x y width height] format.
textBBoxes = [xmin ymin xmax-xmin+1 ymax-ymin+1];
% Remove bounding boxes that only contain one text region
numRegionsInGroup = histcounts(componentIndices);
textBBoxes(numRegionsInGroup == 1, :) = [];
% Show the final text detection result.
ITextRegion = insertShape(colorImage, 'Rectangle', textBBoxes,'LineWidth',3);
figure
imshow(ITextRegion)
title('Detected Text')
textext = ocr(I, textBBoxes);
[textext.Text]
textext=textext.Text;
fid = fopen('textext.Text', 'wt');
fprintf(fid,'%s\n',textext);
fclose(fid);
%Open 'text.txt' file
winopen('textext.Text')
%Write 'word' in text file (upper)
% Clear 'word' variable
caUserInput = char(textext); % Convert from cell to string.
NET.addAssembly('System.Speech');
obj = System.Speech.Synthesis.SpeechSynthesizer;
obj.Volume = 100;
Speak(obj, caUserInput);
THIS IS MY CODE AND I AM NOT GETTING THE TEXT O/P DUE TO NON-MERGING OF TEXT BOXES PLEASE HELP ME WITH IT
Mangaraju Palepu
on 24 May 2021
Edited: Mangaraju Palepu
on 24 May 2021
Regardless of merging bounding boxes. The text will be detected when used OCR. I see no text in your image. so it is obvious that function OCR detected no text.
anyways to merge two bounding boxes they should overlap first. Increase the size of bounding boxes, make them overlap and try to merge. change the valuse expansionAmount in your code.
By the way you totally copied the exaple code from matlab. And only use either regionprops or stoke width variation to remove non text region , the code you copied using both. only one method has to opt.
Walter Roberson
on 25 May 2021
The images were posted by @Nibir Sarker and are probably not the same ones uses by @Saketh Nannaka .
kalpana k
on 24 Nov 2022
Edited: Walter Roberson
on 24 Nov 2022
if you are having the binary image as "I7", follow the below code to merge all the regions into common bounding box as below
RegionAll=regionprops(I7,'BoundingBox');
BBall=[];
for jk=1:length(RegionAll)
Box1=RegionAll(jk).BoundingBox;
Box2=[Box1(1) Box1(2) Box1(1)+Box1(3)-1 Box1(2)+Box1(4)-1];
BBall=[BBall ;Box2];
end
mX=min(BBall(:,1));
mY=min(BBall(:,2));
mW=max(BBall(:,3))-mX;
mH=max(BBall(:,4))-mY;
NewBB=[mX mY mW mH];
1 Comment
Walter Roberson
on 24 Nov 2022
No loop needed
RegionAll=regionprops(I7,'BoundingBox');
AllBoxes = vertcat(RegionAll.BoundingBox);
xy = [AllBoxes(:,1:2), AllBoxes(:,1:2) + AllBoxes(:,3:4));
startX = min(xy(:,1));
startY = min(xy(:,2));
endX = max(xy(:,3));
endY = max(xy(:,4));
BB = [startX, startY, endX - startX, endY - startY];
Categories
Find more on Text, Barcode, and Fiducial Marker Detection and Recognition in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!