I have the following code which, given an image, it extract ROI from it.
Warning: as is, the code will save all extracted ROIs (45 files) on Desktop.
import cv2
extr_path = ('C:\\Users\\Bob\\Desktop\\')
# Read the input image
im = cv2.imread(extr_path + 'extracted.jpg')
# Convert to grayscale and apply Gaussian filtering
im_gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
im_gray = cv2.GaussianBlur(im_gray, (5, 5), 0)
# Threshold the image
ret, im_th = cv2.threshold(im_gray, 90, 255, cv2.THRESH_BINARY_INV)
# Find contours in the image
image, ctrs, hier = cv2.findContours(im_th.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Sort the bounding boxes
sorted_ctrs = sorted(ctrs, key=lambda ctr: cv2.boundingRect(ctr)[0])
# Extract ROI
i = 0
for i, ctr in enumerate(sorted_ctrs):
# Get bounding box
x, y, w, h = cv2.boundingRect(ctr)
# Getting ROI
roi = im[y:y+h, x:x+w]
cv2.imwrite('C:\\Users\\Bob\\Desktop\\' + str(i) + '.jpg', roi)
This is image used to run the code:
This is the result:
Green is ok, like other images.
As you can (barely...) see, there is something wrong with the number five (29.jpg
).
There is a part above the char which miss in the extracted ROI.
I think is a problem with the cv2.boundingRect() function. To be clear, this is an exception. If I give more numbers, let's say it recognize and extract 7 digits on 10 near perfectly. Others have problems like the one above...
Also, I saw that ROI rectangles give themselves automatic dimensions (width and height) to match the digit they found.
I tried to add other image pre-processing like adaptive threshold or medianBlur but it doesn't change. Maybe because the image already satisfy some conditions (black writing on white paper for example...)
I also found a link to another question but I don't understand if the problem is the same of me..
Why this happen ? What I have to modify ? I mean, it is even possible to "give instructions" to the area which bounding rectangle have to crop ?
If someone could help, it would be greatly appreciated.
Thank you
UPDATE 1: tried also with cannyEdge filter but is the same. Dilation and Erosion as well has been tried but the result is the same.. Now I really think that the problem could be the boundingRect function inside OpenCV core.