How can I detect rectangles and get their coordinates in a binary image
40 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
Niklas Persson
il 15 Set 2022
Commentato: Niklas Persson
il 16 Set 2022
Hi,
I'm looking for a way to extract the rectangles of a binary image and get the coordinates of the corners of the rectangles. The location and size of the rectangles can vary, but it will always be black rectangles on a white background. Also, the black border at the edge of the image will be made up of 4 rectangles, see the image below (the numbers are just there to give you an idea of the numbers of rectangles).
I have tried to use the detectHarrisFeatures function, but the problem is that I only get the coordinates of the rectangles, thus I don't know which coordinates makes up a rectangle.
I have also tried to use the bwconncomp function, as I was suggested in this post. It works, but it is slow for larger images and it is possible to end up with a lot of small row rectangles or a lot of small column rectangles. For example the top border can be seen as 2 connected rows, or 120 connected columns.
So I'm looking for a more efficient way to detect the rectangles and retrive the corner coordinates for each.
I have attached two example image in the question.
Any help is highly appriciated
4 Commenti
Matt J
il 15 Set 2022
Modificato: Matt J
il 15 Set 2022
Even if you could get the fewest number of rectangles, you still have ambiguities. Below is an example showing a shape that can be partitioned into the minimum number of rectangles (2) in two different ways. Does your application care which partition is chosen?
Risposta accettata
Image Analyst
il 15 Set 2022
What I'd do first is to get the four perimeter blobs and store those, then fill in that border. Then I'd threshold for black then label the image. Then use ismember to get each blob in turn. Then I'd scan down each image until I hit the blob. Then use find() to find the first and last point in the blob and note it's width and top row. Then scan down until the width changes, which means you're now in a new rectangle so the last one had its bottom row on the prior line. I believe this should work. Give it a try. If you're still unable to do it, post the original image (with no graphics or JPG blurring) in a .PNG file.
3 Commenti
Image Analyst
il 16 Set 2022
Yeah, those would be OK. I didn't notice them at first.
You'll have to modify my algorithm to handle cases where a row cross section might cut through two or more rectangles. The function bwlabel is useful for counting:
Here's a start. Much stuff is left out though.
[rows, columns, numbreOfcolorchannels] = size(binaryImage);
rectCounter = 0; % Keep track of number of rectangles.
width = zeros(rows, 1);
for row = 1 : rows
thisRow = binaryImage
[~, numRegions] = bwlabel(thisRow);
if numRegions == 1
col1 = find(binaryImage, 1, 'first')
if ~isempty(col1)
col2 = find(binaryImage, 1, 'last')
width(row) = col2 - col1;
end
else
% Two or more regions
end
% Write this region to the output image with a value of rectCounter
% Etc.
end
After this you, if you do it right, you should have a labeled image where each rectangle has its own label (ID Number). Start out easy and have just one rectangle intersecting any row. Then adapt it to handle multiple rectangles.
Più risposte (0)
Vedere anche
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!