Home > database >  Remove text at edges using opencv python
Remove text at edges using opencv python

Time:09-23

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

Input Image

Output should be like this with bounding box

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:

enter image description here


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:

enter image description here

res_img (cropped upper part of img):

enter image description here


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:

enter image description here

img2:

enter image description here

img3:

enter image description here

img4:

enter image description here

output_img:

enter image description here


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()
  • Related