OCR - 如何使用 python 识别方框内的数字?
OCR - How to recognize numbers inside square boxes using python?
光学字符识别 (ocr) 的一个问题是当数字位于方框内时它无法正确识别数字。此处讨论了 tesseract 的一个失败示例:Tesseract - How can I recognize numbers in box?
我在这里用 paddleocr 测试:https://www.paddlepaddle.org.cn/hub/scene/ocr
您也可以快速尝试 api,对于此输入图像:
它 returns 没什么..
当我再次尝试这样的图像时:
它 returns 所有数字 successfully.most 这些数字识别(印刷和手写)在正方形内时失败 boxes.for 识别正方形框内的数字我们需要通过删除所有方框,将这些所谓的方框图像中的数字转换为图像中的数字。
我有一些像下面这样的图片:
看,数字外面的完整方框不完全可见,只有部分方框 visible.i 想将这些图像转换为我将通过删除方框而只有数字的图像或这些图像中存在的方框的某些部分,然后希望 number/digit 识别会起作用。
我试过这段代码:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('/content/21.png')
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
linek = np.zeros((11,11),dtype=np.uint8)
linek[...,5]=1
x=cv2.morphologyEx(gray, cv2.MORPH_OPEN, linek ,iterations=800)
gray-=x
plt.imshow(gray)
cv2.imwrite('21_output.jpg', gray)
输出:
也试过这个代码:
import cv2
import numpy as np
import matplotlib.pyplot as plt
#
image = cv2.imread('/content/17.png')
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# Remove vertical
vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,10))
detected_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, vertical_kernel, iterations=2)
cnts = cv2.findContours(detected_lines, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
cv2.drawContours(image, [c], -1, (255,255,255), 2)
image = thresh - detected_lines
plt.imshow( image)
输出:
不幸的是,它无法删除不需要的行 completely.when 它删除了不需要的行,它也删除了部分原始 digit/numbers。
我怎样才能删除图像中每个数字外的那些完整或不完整的方框?提前致谢。
下面的代码对我来说做得不错,但它对超参数敏感:
import cv2
import imutils
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import pyplot as plt
def square_number_box_denoiser(image_path="/content/9.png",is_resize = False, resize_width = 768):
'''
ref : https://pretagteam.com/question/removing-horizontal-lines-in-image-opencv-python-matplotlib
Args :
image_path (str) : path of the image containing numbers/digits inside square box
is_resize (int) : whether to resize the input image or not? default : False
resize_width (int) : resizable image width for resizing the image by maintaining aspect ratio. default : 768
'''
img=cv2.imread(image_path)
if(is_resize):
print("resizing...")
img = imutils.resize(img, width=resize_width)
image = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE)
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# Remove horizontal
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (25,1))
detected_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)
cnts = cv2.findContours(detected_lines, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
cv2.drawContours(image, [c], -1, (255,255,255), 2)
# Repair image
repair_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,6))
result = 255 - cv2.morphologyEx(255 - image, cv2.MORPH_CLOSE, repair_kernel, iterations=2)
# create figure
fig = plt.figure(figsize=(20, 20))
# setting values to rows and column variables
rows = 3
columns = 3
fig.add_subplot(rows, columns, 1)
plt.imshow(img)
fig.add_subplot(rows, columns, 2)
plt.imshow(thresh)
fig.add_subplot(rows, columns, 3)
plt.imshow(detected_lines)
fig.add_subplot(rows, columns, 4)
plt.imshow(image)
fig.add_subplot(rows, columns, 5)
plt.imshow(result)
result = cv2.rotate(result,cv2.ROTATE_90_COUNTERCLOCKWISE)
fig.add_subplot(rows, columns, 6)
plt.imshow(result)
cv2.imwrite("result.jpg", result)
plt.show()
输出:
不调整大小:
768 大小调整:
光学字符识别 (ocr) 的一个问题是当数字位于方框内时它无法正确识别数字。此处讨论了 tesseract 的一个失败示例:Tesseract - How can I recognize numbers in box? 我在这里用 paddleocr 测试:https://www.paddlepaddle.org.cn/hub/scene/ocr 您也可以快速尝试 api,对于此输入图像:
当我再次尝试这样的图像时:
它 returns 所有数字 successfully.most 这些数字识别(印刷和手写)在正方形内时失败 boxes.for 识别正方形框内的数字我们需要通过删除所有方框,将这些所谓的方框图像中的数字转换为图像中的数字。 我有一些像下面这样的图片:
看,数字外面的完整方框不完全可见,只有部分方框 visible.i 想将这些图像转换为我将通过删除方框而只有数字的图像或这些图像中存在的方框的某些部分,然后希望 number/digit 识别会起作用。 我试过这段代码:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('/content/21.png')
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
linek = np.zeros((11,11),dtype=np.uint8)
linek[...,5]=1
x=cv2.morphologyEx(gray, cv2.MORPH_OPEN, linek ,iterations=800)
gray-=x
plt.imshow(gray)
cv2.imwrite('21_output.jpg', gray)
输出:
也试过这个代码:
import cv2
import numpy as np
import matplotlib.pyplot as plt
#
image = cv2.imread('/content/17.png')
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# Remove vertical
vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,10))
detected_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, vertical_kernel, iterations=2)
cnts = cv2.findContours(detected_lines, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
cv2.drawContours(image, [c], -1, (255,255,255), 2)
image = thresh - detected_lines
plt.imshow( image)
输出:
不幸的是,它无法删除不需要的行 completely.when 它删除了不需要的行,它也删除了部分原始 digit/numbers。 我怎样才能删除图像中每个数字外的那些完整或不完整的方框?提前致谢。
下面的代码对我来说做得不错,但它对超参数敏感:
import cv2
import imutils
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import pyplot as plt
def square_number_box_denoiser(image_path="/content/9.png",is_resize = False, resize_width = 768):
'''
ref : https://pretagteam.com/question/removing-horizontal-lines-in-image-opencv-python-matplotlib
Args :
image_path (str) : path of the image containing numbers/digits inside square box
is_resize (int) : whether to resize the input image or not? default : False
resize_width (int) : resizable image width for resizing the image by maintaining aspect ratio. default : 768
'''
img=cv2.imread(image_path)
if(is_resize):
print("resizing...")
img = imutils.resize(img, width=resize_width)
image = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE)
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# Remove horizontal
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (25,1))
detected_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)
cnts = cv2.findContours(detected_lines, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
cv2.drawContours(image, [c], -1, (255,255,255), 2)
# Repair image
repair_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,6))
result = 255 - cv2.morphologyEx(255 - image, cv2.MORPH_CLOSE, repair_kernel, iterations=2)
# create figure
fig = plt.figure(figsize=(20, 20))
# setting values to rows and column variables
rows = 3
columns = 3
fig.add_subplot(rows, columns, 1)
plt.imshow(img)
fig.add_subplot(rows, columns, 2)
plt.imshow(thresh)
fig.add_subplot(rows, columns, 3)
plt.imshow(detected_lines)
fig.add_subplot(rows, columns, 4)
plt.imshow(image)
fig.add_subplot(rows, columns, 5)
plt.imshow(result)
result = cv2.rotate(result,cv2.ROTATE_90_COUNTERCLOCKWISE)
fig.add_subplot(rows, columns, 6)
plt.imshow(result)
cv2.imwrite("result.jpg", result)
plt.show()
输出:
不调整大小:
768 大小调整: