来自计算机屏幕的图像识别
问题描述:
我想从下面的图像中提取文本。我在python中尝试了OCR。但它给了我不正确的结果。来自计算机屏幕的图像识别
我预处理图像中删除下划线,使用canny edge detector增加对比度,然后将其馈送到OCR。不过,我没有得到预期的产出。
由于知识有限,我在增加对比度后尝试将图像中的字符分开。
import cv2
import numpy as np
import os
image_path = os.path.join(os.path.dirname(__file__), "image.png")
im = cv2.imread(image_path)
gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
# converted intermediate pixels to black and white
gray[gray<100] = 0
gray[gray>=100] = 255
gray = gray[~np.all(gray == 255, axis=1)]
gray = gray[:,~np.all(gray == 255, axis=0)]
gray = gray[~np.all(gray == 0, axis=1)]
print (np.where(np.all(gray == 255,axis=0)))
print (gray[:,20:33])
words = np.hsplit(gray, np.where(np.all(gray == 255,axis=0))[0])
i = 0
for word in words:
word = word[:,~np.all(word == 255, axis=0)]
if(word.size):
print (word.shape)
i = i + 1
cv2.imwrite("temp" + str(i) + ".png", word)
它成了这个样子
我再次给这个作为输入pytesseract。它给了我空白输出。
这是我的疑惑。
- 我们可以有一个更好的机制来分隔白色空间上的字符和图像。目前它对我来说似乎非常易碎。
- 我们如何预处理图像以便通过OCR更好地检测。
- 我们可以使用神经网络或SVM在这里就像我们用于MNIST Digits dataset
短指针是确定的,如果它似乎过于宽泛。解决这类问题的最佳方法是什么?
答
这个答案实现什么在我的评论说。
我改变你的代码一点点,使用OpenCV的忍住形式。该代码是用Python 3.5
要提取的数字写的,我总结了图像纵列和规模所产生的阵列来获得check
。我说你已经切断,有效地摆脱下划线的gray
图像这里工作。
x_sum = np.sum(gray, axis = 0)
check = ((x_sum)/np.max(x_sum)*10)
该阵列现在可以使用阈值进行比较,以确定其中一个字母/数字位于诸如地区:
plt.imshow(gray, cmap='gray')
x_sum = np.sum(gray, axis = 0)
check = ((x_sum)/np.max(x_sum)*10)
plt.plot((check<8).astype(int))
plt.show()
现在我们将使用这些信息修改图像并擦除校验阵列被赋值为0的区域,例如:
for idx,i in enumerate((check<8).astype(int)):
if i < 1:
gray[:,idx] = 255
因此,我们有这样的形象:
这可以进一步加工只是你已经在做。这提供了分离式字母/数字,然后可以进行后处理学习。
下一步,您将要处理的是缩放/调整要用相同数量的要素描述的字母/图像。
最后,您可以使用预训练分类器预测最可能的字母/数字。
完整的代码这里提供:
import numpy as np
import os
import matplotlib.pyplot as plt
from scipy.stats import mstats
import scipy
from matplotlib import gridspec
from PIL import Image
image = Image.open("testl.png")
f = image.convert('I')
gray = np.array(f)
gray[gray<200] = 0
gray[gray>=200] = 255
gray = gray[~np.all(gray == 255, axis=1)]
gray = gray[:,~np.all(gray == 255, axis=0)]
gray = gray[~np.all(gray == 0, axis=1)]
plt.imshow(gray, cmap='gray')
x_sum = np.sum(gray, axis = 0)
check = ((x_sum)/np.max(x_sum)*10)
plt.plot((check<8).astype(int))
plt.show()
plt.matshow(gray)
plt.show()
for idx,i in enumerate((check<8).astype(int)):
if i < 1:
gray[:,idx] = 255
plt.matshow(gray)
plt.show()
words = np.hsplit(gray, np.where(np.all(gray >= 200,axis=0))[0])
gs = gridspec.GridSpec(1,len(words))
fig = plt.figure(figsize=(len(words),1))
i = 0
for word in words:
word = word[:,~np.all(word >= 230, axis=0)]
if(word.size):
ax = fig.add_subplot(gs[i])
print (word.shape)
i = i + 1
ax.matshow(word, aspect = 'auto')
plt.show()
这次终于得到所有分隔的字母/数字组成,例如:
你知道,所有单个数字/字母之间有一点点白色空间。第一步是找到空白空间。因此,您可以对图像进行灰度调整,然后总结沿着列的值。沿着图像的x轴的最小值是白色空间的位置。 –