来自计算机屏幕的图像识别

问题描述:

我想从下面的图像中提取文本。我在python中尝试了OCR。但它给了我不正确的结果。来自计算机屏幕的图像识别

Test image

我预处理图像中删除下划线,使用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) 

它成了这个样子

Cropped images

我再次给这个作为输入pytesseract。它给了我空白输出。

这是我的疑惑。

  1. 我们可以有一个更好的机制来分隔白色空间上的字符和图像。目前它对我来说似乎非常易碎。
  2. 我们如何预处理图像以便通过OCR更好地检测。
  3. 我们可以使用神经网络或SVM在这里就像我们用于MNIST Digits dataset

短指针是确定的,如果它似乎过于宽泛。解决这类问题的最佳方法是什么?

+0

你知道,所有单个数字/字母之间有一点点白色空间。第一步是找到空白空间。因此,您可以对图像进行灰度调整,然后总结沿着列的值。沿着图像的x轴的最小值是白色空间的位置。 –

这个答案实现什么在我的评论说。

我改变你的代码一点点,使用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() 

enter image description here

现在我们将使用这些信息修改图像并擦除校验阵列被赋值为0的区域,例如:

for idx,i in enumerate((check<8).astype(int)):  
    if i < 1: 
     gray[:,idx] = 255 

因此,我们有这样的形象:

enter image description here

这可以进一步加工只是你已经在做。这提供了分离式字母/数字,然后可以进行后处理学习。

下一步,您将要处理的是缩放/调整要用相同数量的要素描述的字母/图像。

最后,您可以使用预训练分类器预测最可能的字母/数字。

完整的代码这里提供:

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

这次终于得到所有分隔的字母/数字组成,例如:

enter image description here