如何从存在轻微背景的图像中提取文本?
How to extract text from an image with a slight background present?
我想从图像中提取文本,我收到的输出不是很准确。我想知道我是否可以采取任何额外的步骤来进一步处理图像以提高此 OCR 的准确性。
我研究了一些处理图像和改进 OCR 结果的不同方法。图片很小,我稍微放大了一点,但没有用。
图像将始终是水平的,除数字外不会出现其他文本。最大数量将达到 55000。
相关图片示例:
图像处理后,我的图像在 X 轴和 Y 轴上放大了 4 倍。并去除了一些饱和度,尽管这根本不会提高准确性。
image = self._process(scale=6, iterations=2)
text = pytesseract.image_to_string(image, config="--psm 7")
我的处理方法如下:
# Resize and desaturate.
image = cv2.resize(image, None, fx=scale, fy=scale,
interpolation=cv2.INTER_CUBIC)
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Apply dilation and erosion.
kernel = np.ones((1, 1), np.uint8)
image = cv2.dilate(image, kernel, iterations=iterations)
image = cv2.erode(image, kernel, iterations=iterations)
return image
预期:“10411”
实际值是多种多样的,通常是无法识别的字符串,或者解析了一些数字但准确率太低而无法使用。
我没有使用 OCR 的经验,但我认为您走在正确的轨道上:增加图像大小,使算法有更多像素可以使用,并增加数字和背景之间的区别。
我添加的技巧:thresholding the image, which creates a mask where only the white pixels remain. There were a few white blobs that were not numbers, so I used findContours 将那些不需要的斑点涂成黑色。
结果:
代码:
import numpy as np
import cv2
# load image
image = cv2.imread('number.png')
# resize image
image = cv2.resize(image,None,fx=5, fy=5, interpolation = cv2.INTER_CUBIC)
# create grayscale
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# perform threshold
retr, mask = cv2.threshold(gray_image, 230, 255, cv2.THRESH_BINARY)
# find contours
ret, contours, hier = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# draw black over the contours smaller than 200 - remove unwanted blobs
for cnt in contours:
# print contoursize to detemine threshold
print(cv2.contourArea(cnt))
if cv2.contourArea(cnt) < 200:
cv2.drawContours(mask, [cnt], 0, (0), -1)
#show image
cv2.imshow("Result", mask)
cv2.imshow("Image", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
我想从图像中提取文本,我收到的输出不是很准确。我想知道我是否可以采取任何额外的步骤来进一步处理图像以提高此 OCR 的准确性。
我研究了一些处理图像和改进 OCR 结果的不同方法。图片很小,我稍微放大了一点,但没有用。
图像将始终是水平的,除数字外不会出现其他文本。最大数量将达到 55000。
相关图片示例:
图像处理后,我的图像在 X 轴和 Y 轴上放大了 4 倍。并去除了一些饱和度,尽管这根本不会提高准确性。
image = self._process(scale=6, iterations=2)
text = pytesseract.image_to_string(image, config="--psm 7")
我的处理方法如下:
# Resize and desaturate.
image = cv2.resize(image, None, fx=scale, fy=scale,
interpolation=cv2.INTER_CUBIC)
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Apply dilation and erosion.
kernel = np.ones((1, 1), np.uint8)
image = cv2.dilate(image, kernel, iterations=iterations)
image = cv2.erode(image, kernel, iterations=iterations)
return image
预期:“10411”
实际值是多种多样的,通常是无法识别的字符串,或者解析了一些数字但准确率太低而无法使用。
我没有使用 OCR 的经验,但我认为您走在正确的轨道上:增加图像大小,使算法有更多像素可以使用,并增加数字和背景之间的区别。
我添加的技巧:thresholding the image, which creates a mask where only the white pixels remain. There were a few white blobs that were not numbers, so I used findContours 将那些不需要的斑点涂成黑色。
结果:
代码:
import numpy as np
import cv2
# load image
image = cv2.imread('number.png')
# resize image
image = cv2.resize(image,None,fx=5, fy=5, interpolation = cv2.INTER_CUBIC)
# create grayscale
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# perform threshold
retr, mask = cv2.threshold(gray_image, 230, 255, cv2.THRESH_BINARY)
# find contours
ret, contours, hier = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# draw black over the contours smaller than 200 - remove unwanted blobs
for cnt in contours:
# print contoursize to detemine threshold
print(cv2.contourArea(cnt))
if cv2.contourArea(cnt) < 200:
cv2.drawContours(mask, [cnt], 0, (0), -1)
#show image
cv2.imshow("Result", mask)
cv2.imshow("Image", image)
cv2.waitKey(0)
cv2.destroyAllWindows()