簡體   English   中英

如何從圖像中刪除背景線條和形狀以進行文本提取?

[英]How to remove background lines and shapes from an image for text extraction?

我只想提取文本並從下圖中刪除所有其他內容:

輸入圖像

現在,我想刪除除矩形形狀中的文本之外的所有其他內容。 那是我的代碼:

import cv2
import pytesseract
import numpy as np
from imutils.perspective import four_point_transform

pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"

# Load image, convert to HSV, color threshold to get mask
image = cv2.imread('1.png')
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower = np.array([0, 0, 0])
upper = np.array([100, 175, 110])
mask = cv2.inRange(hsv, lower, upper)

# Morph close to connect individual text into a single contour
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
close = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=3)

# Find rotated bounding box then perspective transform
cnts = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
rect = cv2.minAreaRect(cnts[0])
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(image,[box],0,(36,255,12),2)
warped = four_point_transform(255 - mask, box.reshape(4, 2))

# OCR
data = pytesseract.image_to_string(warped, lang='eng', config='--psm 6')
print(data)

cv2.imshow('mask', mask)
cv2.imshow('close', close)
cv2.imshow('warped', warped)
cv2.imshow('image', image)
cv2.waitKey()

這是代碼的output:

輸出

我的代碼的錯誤是它遮蔽了圖像中的所有內容,我只想提取文本,而不是其他內容:

輸出

由於您的圖像中有“完美”的矩形,我想出了以下方法:

  1. 灰度和反向二值化輸入圖像以消除可能的偽影,並在黑色背景上有白色框和文本。

  2. 在下文中,將使用模板匹配來找到感興趣的框的左上角。 所以,設置一個模板和面具來模仿那些左上角。

    模板本身類似於 50 像素長和 20 像素高的“角”,因為所有感興趣的框至少具有以下尺寸:

    模板

    相應的掩碼將模板限制為沿“角”的 5 個像素寬的“條紋”:

    模板掩碼

    由於所有文本與框的邊界至少有 5 個像素的邊距,因此將有“完美”的匹配結果,因為沒有文本干擾匹配。

  3. 從“完美”匹配結果中,推導出每個感興趣框的(x, y)坐標,並進行迭代。

    盒子里充滿了一些灰色(由於一開始的二值化,圖像中只有黑色和白色)

    滿溢

    然后使用該灰色遮罩:

    蒙面

  4. 由此確定邊界矩形,並將該部分從原始圖像復制粘貼到一些干凈的圖像中。 此外,對內容執行pytesseract

這是完整的代碼:

import cv2
import numpy as np
import pytesseract

# Read image as grayscale
img = cv2.imread('M7X8C.png', cv2.IMREAD_GRAYSCALE)

# Inverse binarize image to get rid of possible artifacts, and to have
# white boxes and text on black background
thr = cv2.threshold(img, 128, 255, cv2.THRESH_BINARY_INV)[1]

# Set up a template and mask mimicking the upper left corner of the
# boxes of interest
templ = np.full((20, 50), 255, dtype=np.uint8)
templ[1:, 1:] = 0
mask = np.full_like(templ, 255)
mask[5:, 5:] = 0

# Template matching
res = cv2.matchTemplate(thr, templ, cv2.TM_CCORR_NORMED, mask=mask)

# Extract upper left corners of the boxes of interest
boxes_tl = np.argwhere(res == 1)

# Initialize new clean image
clean = np.full_like(img, 255)

# For each upper left corner...
for i in np.arange(boxes_tl.shape[0]):

    # Get coordinates of upper left corner
    y, x = boxes_tl[i, :]
    print('x: {}, y: {}'.format(x, y))

    # Flood fill inner part of box, and mask that area
    box_mask = cv2.floodFill(thr.copy(), None, (x + 1, y + 1), 128)[1] == 128

    # Extract the bounding rectangle of that area
    x, y, w, h = cv2.boundingRect(box_mask.astype(np.uint8))

    # Copy box content to clean image
    clean[y:y+h, x:x+w] = img[y:y+h, x:x+w]

    # Run pytesseract on box content
    text = pytesseract.image_to_string(thr[y:y+h, x:x+w], config='--psm 6')
    print(text.replace('\f', ''))

# Output
cv2.imshow('clean', clean)
cv2.waitKey(0)

那是干凈的圖像:

干凈的

而且,這是前兩個pytessract結果:

x: 1, y: 0
PGGEOS KKCI 100600

x: 199, y: 39
ISOL
EMBD
CB
400
XXX

如您所見,結果並不完美( S而不是5 ),很可能是由於等寬字體。 為這種字體獲取(或生成)一些 Tesseract traineddata肯定有助於克服這個問題。

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.19041-SP0
Python:        3.9.1
PyCharm:       2021.1.1
NumPy:         1.19.5
OpenCV:        4.5.2
pytesseract:   5.0.0-alpha.20201127
----------------------------------------

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM