使用 opencv python 删除边缘的文本

Remove text at edges using opencv python

我想去掉边缘的文字,在中间的文字周围画一个边框,我写了下面的代码,但是没有用

输入图片

带边界框的输出应该是这样的

import cv2
import numpy as np

# read image
image = cv2.imread(r'C:\TABLEWORK\remove edged text and autoadjust bbox.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)

我会非常感谢你

假设我们知道如何去除底部边缘的文字,我们可以将图像旋转 90 度,并去除顶部边缘的文字——旋转并去除 4 次。

删除底部边缘的文本:

膨胀:
无需申请GaussianBlur,无需开通
我们可以简单地用水平线形内核进行膨胀:

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 1))  # 30 pixel seems long enough.
dilate = cv2.dilate(thresh, kernel, iterations=1)

结果:


迭代轮廓,并移除底部(如果边界矩形触及底部):

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

绘制的矩形:

res_imgimg 的上半部分被裁剪):


正在执行方法 crop_buttom_text:
假设方法 crop_buttom_text(img) returns img 的顶部,没有触及底部边缘的文本。

我们可以执行该方法 4 次 - 每次将图像旋转 90 度:

# read image
image = cv2.imread(r'C:\TABLEWORK\remove edged text and autoadjust bbox.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)

结果:

img1:

img2:

img3:

img4:

output_img:


完整代码:

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.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()