I want to remove the text at the edges and draw a bounding box around the center text, I have written the following code but it does not work
Input image
Output should be like this with bounding box
import cv2
import numpy as np
# read image
image = cv2.imread(r'C:\TABLEWORK\remove edged text and autoadjust bbox\3.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (9,9), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV cv2.THRESH_OTSU)[1]
# Create rectangular structuring element and dilate
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (4,4))
dilate = cv2.dilate(thresh, kernel, iterations=5)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (10,10))
dilate = cv2.morphologyEx(dilate, cv2.MORPH_OPEN, kernel)
# Find contours and draw rectangle
cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
x,y,w,h = cv2.boundingRect(c)
cv2.rectangle(image, (x, y), (x w, y h), (36,255,12), 2)
plt.imshow(image)
I will be very thankful to you
CodePudding user response:
Assume we know how to remove the text at the bottom edge, we can rotate the image by 90 degrees, and remove the text at the top edge - rotate and remove 4 times.
Removing the text at the bottom edge:
Dilating:
There is no need to apply GaussianBlur
, and no need for opening.
We may simply dilate with horizontal line shaped kernel:
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 1)) # 30 pixel seems long enough.
dilate = cv2.dilate(thresh, kernel, iterations=1)
Result:
Iterating the contours, and removing the bottom part (if bounding rectangle touches the bottom):
for c in cnts:
x, y, w, h = cv2.boundingRect(c)
y2 = y h # Bottom y coordinate of the bounding rectangle
if (y2 >= img.shape[0]):
# If the rectangle touches the bottom of the img
res_img = res_img[0:y-1, :].copy() # Crop rows from first row to row y-1
cv2.rectangle(img, (x, y), (x w, y h), (36, 255, 12), 2)
cv2.imshow('img', img) # Show img for testing
cv2.imshow('res_img', res_img) # Show img for testing
cv2.waitKey()
Drawn rectangle:
res_img
(cropped upper part of img
):
Executing the method crop_buttom_text
:
Assume the method crop_buttom_text(img)
returns the top part of img
, without the text that touches the bottom edge.
We can execute the method 4 times - each time the image is rotated by 90 degrees:
# read image
image = cv2.imread(r'C:\TABLEWORK\remove edged text and autoadjust bbox\3.jpg')
img1 = crop_buttom_text(image)
img2 = crop_buttom_text(np.rot90(img1)) # Rotate by 90 degrees and crop.
img3 = crop_buttom_text(np.rot90(img2)) # Rotate by 90 degrees and crop.
img4 = crop_buttom_text(np.rot90(img3)) # Rotate by 90 degrees and crop.
output_img = np.rot90(img4)
Result:
img1
:
img2
:
img3
:
img4
:
output_img
:
Complete code:
import cv2
import numpy as np
def crop_buttom_text(img):
""" Remove the text from the bottom edge of img """
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#blur = cv2.GaussianBlur(gray, (9,9), 0) # No need for blurring
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV cv2.THRESH_OTSU)[1]
# Create rectangular structuring element and dilate
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 1)) # Use horizontal line as kernel - dilate horizontally.
dilate = cv2.dilate(thresh, kernel, iterations=1)
#kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (10,10))
#dilate = cv2.morphologyEx(dilate, cv2.MORPH_OPEN, kernel) # No need for opening
# Find contours and draw rectangle
cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2] # [-2] indexing takes return value before last (due to OpenCV compatibility issues).
#cnts = cnts[0] if len(cnts) == 2 else cnts[1] # [-2] is shorter....
res_img = img.copy() # Copy img to res_img - in case there is no edges text.
for c in cnts:
x, y, w, h = cv2.boundingRect(c)
y2 = y h # Bottom y coordinate of the bounding rectangle
if (y2 >= img.shape[0]):
# If the rectangle touches the bottom of the img
res_img = res_img[0:y-1, :].copy() # Crop rows from first row to row y-1
return res_img
# read image
image = cv2.imread(r'C:\TABLEWORK\remove edged text and autoadjust bbox\3.jpg')
img1 = crop_buttom_text(image)
img2 = crop_buttom_text(np.rot90(img1)) # Rotate by 90 degrees and crop.
img3 = crop_buttom_text(np.rot90(img2)) # Rotate by 90 degrees and crop.
img4 = crop_buttom_text(np.rot90(img3)) # Rotate by 90 degrees and crop.
output_img = np.rot90(img4)
cv2.imshow('img1', img1) # Show img for testing
cv2.imshow('img2', img2)
cv2.imshow('img3', img3)
cv2.imshow('img4', img4)
cv2.imshow('output_img', output_img)
cv2.waitKey()
cv2.destroyAllWindows()