我自己的Python OCR程序

我自己的Python OCR程序,python,arrays,artificial-intelligence,ocr,Python,Arrays,Artificial Intelligence,Ocr,我还是一个初学者,但我想写一个字符识别程序。这个程序还没有准备好。我编辑了很多,因此评论可能不完全匹配。我将使用8连接性来标记连接的组件 from PIL import Image import numpy as np im = Image.open("D:\\Python26\\PYTHON-PROGRAMME\\bild_schrift.jpg") w,h = im.size w = int(w) h = int(h) #2D-Array for area area = [] for

我还是一个初学者,但我想写一个字符识别程序。这个程序还没有准备好。我编辑了很多,因此评论可能不完全匹配。我将使用8连接性来标记连接的组件

from PIL import Image
import numpy as np

im = Image.open("D:\\Python26\\PYTHON-PROGRAMME\\bild_schrift.jpg")

w,h = im.size
w = int(w)
h = int(h)

#2D-Array for area
area = []
for x in range(w):
    area.append([])
    for y in range(h):
        area[x].append(2) #number 0 is white, number 1 is black

#2D-Array for letter
letter = []
for x in range(50):
    letter.append([])
    for y in range(50):
        letter[x].append(0)

#2D-Array for label
label = []
for x in range(50):
    label.append([])
    for y in range(50):
        label[x].append(0)

#image to number conversion
pix = im.load()
threshold = 200
for x in range(w):
    for y in range(h):
        aaa = pix[x, y]
        bbb = aaa[0] + aaa[1] + aaa[2] #total value
        if bbb<=threshold:
            area[x][y] = 1
        if bbb>threshold:
            area[x][y] = 0
np.set_printoptions(threshold='nan', linewidth=10)

#matrix transponation
ccc = np.array(area) 
area = ccc.T #better solution?

#find all black pixel and set temporary label numbers
i=1
for x in range(40): # width (later)
    for y in range(40): # heigth (later)
        if area[x][y]==1:
            letter[x][y]=1
            label[x][y]=i
            i += 1

#connected components labeling
for x in range(40): # width (later)
    for y in range(40): # heigth (later)
        if area[x][y]==1:
            label[x][y]=i
            #if pixel has neighbour:
            if area[x][y+1]==1:
                #pixel and neighbour get the lowest label             
                pass # tomorrows work
            if area[x+1][y]==1:
                #pixel and neighbour get the lowest label             
                pass # tomorrows work            
            #should i also compare pixel and left neighbour?

#find width of the letter
#find height of the letter
#find the middle of the letter
#middle = [width/2][height/2] #?
#divide letter into 30 parts --> 5 x 6 array

#model letter
#letter A-Z, a-z, 0-9 (maybe more)

#compare each of the 30 parts of the letter with all model letters
#make a weighting

#print(letter)

im.save("D:\\Python26\\PYTHON-PROGRAMME\\bild2.jpg")
print('done')
从PIL导入图像
将numpy作为np导入
im=Image.open(“D:\\Python26\\PYTHON-program\\bild\u schrift.jpg”)
w、 h=im尺寸
w=int(w)
h=int(h)
#二维面阵
面积=[]
对于范围(w)内的x:
area.append([])
对于范围(h)内的y:
区域[x]。追加(2)#数字0为白色,数字1为黑色
#二维字母数组
字母=[]
对于范围(50)内的x:
信函。附加([])
对于范围(50)内的y:
字母[x]。追加(0)
#标签的二维数组
标签=[]
对于范围(50)内的x:
label.append([])
对于范围(50)内的y:
标签[x]。追加(0)
#图像到数字的转换
pix=im.load()
阈值=200
对于范围(w)内的x:
对于范围(h)内的y:
aaa=pix[x,y]
bbb=aaa[0]+aaa[1]+aaa[2]#总价值
如果BBB阈值为:
面积[x][y]=0
np.设置打印选项(阈值=nan',线宽=10)
#矩阵转置
ccc=np.阵列(面积)
面积=ccc.T#更好的解决方案?
#查找所有黑色像素并设置临时标签编号
i=1
对于范围(40)内的x:#宽度(稍后)
对于范围(40)内的y:#高度(稍后)
如果面积[x][y]==1:
字母[x][y]=1
标签[x][y]=i
i+=1
#连接组件标签
对于范围(40)内的x:#宽度(稍后)
对于范围(40)内的y:#高度(稍后)
如果面积[x][y]==1:
标签[x][y]=i
#如果像素有邻居:
如果面积[x][y+1]==1:
#像素和邻居得到最低的标签
通过明天的工作
如果面积[x+1][y]==1:
#像素和邻居得到最低的标签
通过明天的工作
#我应该也比较像素和左邻域吗?
#找出字母的宽度
#找出字母的高度
#找到信的中间部分
#中间=[宽度/2][高度/2]#?
#将字母分成30部分-->5 x 6数组
#范文
#字母A-Z,A-Z,0-9(可能更多)
#将信函的30个部分中的每一部分与所有模型信函进行比较
#加权
#印刷品(信件)
im.save(“D:\\Python26\\PYTHON-program\\bild2.jpg”)
打印(‘完成’)

OCR非常非常难。即使是计算机生成的字符,如果您事先不知道字体和字号,这也是相当有挑战性的。即使你完全匹配字符,我也不会称之为“开始”编程项目;这很微妙

如果你想识别扫描或手写字符,那就更难了——你需要使用高级数学、算法和机器学习。关于这个话题,有相当多的书和数千篇文章,所以你不需要重新发明轮子

我佩服你的努力,但我认为你还没有取得足够的进展来克服任何实际困难。到目前为止,您只是随机探索像素并将它们从一个阵列复制到另一个阵列。你实际上还没有做任何比较,我也不确定你“随机漫步”的目的

  • 为什么是随机的?编写正确的随机算法相当困难。我建议首先从确定性算法开始
  • 为什么要从一个数组复制到另一个数组?为什么不直接比较呢
当你进行比较时,你将不得不面对这样一个事实,即图像与“原型”并不完全相同,你将如何处理这个问题还不清楚


不过,根据您目前编写的代码,我有一个想法:尝试编写一个程序,在图像中的“迷宫”中找到自己的方向。输入将是图像,加上开始像素和目标像素。输出是一条从起点到目标的迷宫路径。这是一个比OCR容易得多的问题-解决迷宫是计算机的一大优势-但它仍然很有趣和具有挑战性。

OCR非常非常困难!使用什么方法尝试OCR将取决于您尝试完成的内容(手写识别、计算机生成的文本阅读等)

然而,要开始学习,请阅读神经网络和OCR。以下是一些关于该主题的文章:

使用您喜爱的搜索引擎查找信息


玩得开心

OCR确实不是一项容易的任务。这就是为什么文字验证码仍然有效:)

为了只讨论字母提取而不是模式识别,您正在使用的分离字母的技术称为。因为您要求一种更有效的方法来实现这一点,所以请尝试实现本文中描述的双过程算法。另一个描述可以在文章中找到

编辑:下面是我建议的算法的实现:

import sys
from PIL import Image, ImageDraw

class Region():
    def __init__(self, x, y):
        self._pixels = [(x, y)]
        self._min_x = x
        self._max_x = x
        self._min_y = y
        self._max_y = y

    def add(self, x, y):
        self._pixels.append((x, y))
        self._min_x = min(self._min_x, x)
        self._max_x = max(self._max_x, x)
        self._min_y = min(self._min_y, y)
        self._max_y = max(self._max_y, y)

    def box(self):
        return [(self._min_x, self._min_y), (self._max_x, self._max_y)]

def find_regions(im):
    width, height  = im.size
    regions = {}
    pixel_region = [[0 for y in range(height)] for x in range(width)]
    equivalences = {}
    n_regions = 0
    #first pass. find regions.
    for x in xrange(width):
        for y in xrange(height):
            #look for a black pixel
            if im.getpixel((x, y)) == (0, 0, 0, 255): #BLACK
                # get the region number from north or west
                # or create new region
                region_n = pixel_region[x-1][y] if x > 0 else 0
                region_w = pixel_region[x][y-1] if y > 0 else 0

                max_region = max(region_n, region_w)

                if max_region > 0:
                    #a neighbour already has a region
                    #new region is the smallest > 0
                    new_region = min(filter(lambda i: i > 0, (region_n, region_w)))
                    #update equivalences
                    if max_region > new_region:
                        if max_region in equivalences:
                            equivalences[max_region].add(new_region)
                        else:
                            equivalences[max_region] = set((new_region, ))
                else:
                    n_regions += 1
                    new_region = n_regions

                pixel_region[x][y] = new_region

    #Scan image again, assigning all equivalent regions the same region value.
    for x in xrange(width):
        for y in xrange(height):
                r = pixel_region[x][y]
                if r > 0:
                    while r in equivalences:
                        r = min(equivalences[r])

                    if not r in regions:
                        regions[r] = Region(x, y)
                    else:
                        regions[r].add(x, y)

    return list(regions.itervalues())

def main():
    im = Image.open(r"c:\users\personal\py\ocr\test.png")
    regions = find_regions(im)
    draw = ImageDraw.Draw(im)
    for r in regions:
        draw.rectangle(r.box(), outline=(255, 0, 0))
    del draw 
    #im.show()
    output = file("output.png", "wb")
    im.save(output)
    output.close()

if __name__ == "__main__":
    main()

这并不是100%完美,但因为你这样做只是为了学习,这可能是一个很好的起点。有了每个字符的边界框,您现在可以像其他人在这里建议的那样使用神经网络。

现在大多数OCR算法都基于神经网络算法。这是一个很好的开始。基于可用的Hopfield模型,我用python构建了一个非常基本的图像识别算法,类似于您所描述的。我已经发布了完整的来源。这是一个玩具项目,不适合真正的OCR,但可以让你开始在正确的方向

Hopfield模型用作自联想存储器来存储和调用一组位图图像。通过计算相应的权重矩阵来存储图像。此后,从任意配置开始,存储器将精确地安置在存储的图像上,该图像在汉明距离方面最接近于开始配置因此,如果存储图像的版本不完整或损坏,网络