I have the image below with almost all background in black.
Is there a way to crop rectangles surrounded by black without know the coordinates, were:
- height > 400px
- height about 144px
- height about 40px
I’m not interested in the blue rectangle (were height is about 45px) that is above each big rectangle.
I’d like to store the cropped rectangles in memory in order to make further processing with them. So for this
input image would be 4 images stored in memory like below. Thanks in advance for any help.
Image 1:
Image 2
Image 3:
Image 4:
UPDATE
Trying step by step Mark’s solution, I’m getting different output in this steps:
# Threshold image to get white regions of interest on black background
_, thr = cv.threshold(grey,0, 255, cv.THRESH_BINARY)
cv.imwrite('DEBUG-thr.png', thr)
I’ve tested changing to several different values like (0,127), (0,50), (127, 255), etc and I cannot get similar output to yours DEBUG-thr.png
This is what I get with (0,255) cv.threshold(grey,0, 255, cv.THRESH_BINARY)
This is my python and opencv version (running within WSL Ubuntu)
$ python
Python 3.12.0 (main, Oct 21 2023, 17:42:12) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> cv2.__version__
'4.8.1'
>>>
UPDATE2
I understand why the output is different for me. I tried your script with my actual input image (see below), that has gray background, and your script takes as input the black background image I show as input in this question. I’ve shown the black background image because I made some attempts previously to get my goal with imagemagick in bash.
2
Answers
Per the discussion, you seem happy to go with an OpenCV solution, so I made you one. I didn’t pay too much attention to extracting the exact items you were looking for with all the criteria, I just extracted all the contours taller than 35px. You can dink around with the exact heights/widths/colours that interest you:
This is the output from the program:
These are the debug images in the order that the processing generates them, and also some of the extracted images:
I can do the following in Imagemagick 7 to get each non-black-containing regions using connected components filtering.
Threshold. Then get any region larger than 20000 pixels in area. Then keep only the white ones, i.e. gray(255). Then print only the bounding boxes of the regions. Then loop over each region and filter on height an also on standard deviation (to discard near constant regions). Then crop those regions that pass.
Resulting Crops:
ADDITION
Here is an alternate that get the full rows of regions.
Results: