python生成漢字圖片字庫


  最近做文檔識別方面的項目,做漢字識別需要建立字庫,在網上找了各種OCR,感覺都不好,這方面的技術應該比較成熟了,OCR的軟件很多,但沒有找到幾篇有含金量量的論文,也沒有看到哪位大牛公開字庫,我用pygame渲染字體來生成字庫,也用PIL對整齊的圖片進行切割得到字庫。

pygame渲染字體來生成字庫

  用pygame渲染字體我參考的這篇文章,根據GB2323-8標准,漢語中常用字3500個,覆蓋了99.7%的使用率,加上次常用共6763個,覆蓋99.99%的使用率。先生成一個字體圖片,從網上找來3500個常用漢字,對每一個子按字體進行渲染:

 1 def pasteWord(word):
 2     '''輸入一個文字,輸出一張包含該文字的圖片'''
 3     pygame.init()
 4     font = pygame.font.Font(os.path.join("./fonts", "a.ttf"), 22)
 5     text = word.decode('utf-8')
 6     imgName = "E:/dataset/chinesedb/chinese/"+text+".png"
 7     paste(text,font,imgName)
 8         
 9 def paste(text,font,imgName,area = (0, -9)):
10     '''根據字體,將一個文字黏貼到圖片上,並保存'''
11     im = Image.new("RGB", (32, 32), (255, 255, 255))
12     rtext = font.render(text, True, (0, 0, 0), (255, 255, 255))
13     sio = StringIO.StringIO()
14     pygame.image.save(rtext, sio)
15     sio.seek(0)
16     line = Image.open(sio)
17     im.paste(line, area)
18     #im.show()
19     im.save(imgName)

 

  渲染圖片次數多總是報錯,對於渲染失敗的文字我又重試,最終得到了一個包含3510字(加上10個數字)的字庫:

字符分割生成字庫

  另外一種辦法就是把3500個字放在word排好,然后轉PDF保存成圖片,像下面這樣:

  

  密密麻麻的字,但非常整齊,不需要什么圖片處理算法,只要找到空白的行和列,按行和列就可以進行切割,切割出來也好,只要保存有序切割,切出來的圖片依然可以與字對應,下面是切割的代碼:

 1 #!encoding=utf-8
 2 import Image
 3 import os
 4  
 5 def yStart(grey):
 6     m,n = grey.size
 7     for j in xrange(n):
 8         for i in xrange(m):
 9             if grey.getpixel((i,j)) == 0:
10                 return j
11 def yEnd(grey):
12     m,n = grey.size
13     for j in xrange(n-1,-1,-1):
14         for i in xrange(m):
15             if grey.getpixel((i,j)) == 0:
16                 return j
17                  
18 def xStart(grey):
19     m,n = grey.size
20     for i in xrange(m):
21         for j in xrange(n):
22             if grey.getpixel((i,j)) == 0:
23                 return i
24 def xEnd(grey):
25     m,n = grey.size
26     for i in xrange(m-1,-1,-1):
27         for j in xrange(n):
28             if grey.getpixel((i,j)) == 0:
29                 return i
30 def xBlank(grey):
31     m,n = grey.size
32     blanks = []
33     for i in xrange(m):
34         for j in xrange(n):
35             if grey.getpixel((i,j)) == 0:
36                 break
37         if j == n-1:
38             blanks.append(i)
39     return blanks
40      
41 def yBlank(grey):
42     m,n = grey.size
43     blanks = []
44     for j in xrange(n):
45         for i in xrange(m):
46             if grey.getpixel((i,j)) == 0:
47                 break
48         if i == m-1:
49             blanks.append(j)
50     return blanks
51  
52 def getWordsList():
53     f = open('3500.txt')
54     line = f.read().strip()
55     wordslist = line.split(' ')
56     f.close()
57     return wordslist
58      
59 count = 0
60 wordslist = []
61 def getWordsByBlank(img,path):
62     '''根據行列的空白取圖片,效果不錯'''
63     global count
64     global wordslist
65     grey = img.split()[0]   
66     xblank = xBlank(grey)
67     yblank = yBlank(grey)   
68     #連續的空白像素可能不止一個,但我們只保留連續區域的第一個空白像素和最后一個空白像素,作為文字的起點和終點
69     xblank = [xblank[i] for i in xrange(len(xblank)) if i == 0 or i == len(xblank)-1 or not (xblank[i]==xblank[i-1]+1 and xblank[i]==xblank[i+1]-1)]
70     yblank = [yblank[i] for i in xrange(len(yblank)) if i == 0 or i == len(yblank)-1 or not (yblank[i]==yblank[i-1]+1 and yblank[i]==yblank[i+1]-1)]    
71     for j in xrange(len(yblank)/2):
72         for i in xrange(len(xblank)/2):
73             area = (xblank[i*2],yblank[j*2],xblank[i*2+1]+32,yblank[j*2]+32)#這里固定字的大小是32個像素
74             #area = (xblank[i*2],yblank[j*2],xblank[i*2+1],yblank[j*2+1])
75             word = img.crop(area)           
76             word.save(path+wordslist[count]+'.png')
77             count += 1
78             if count >= len(wordslist):
79                 return
80  
81  
82 def getWordsFormImg(imgName,path):
83     png = Image.open(imgName,'r')
84     img = png.convert('1')
85     grey = img.split()[0]
86     #先剪出文字區域
87     area = (xStart(grey)-1,yStart(grey)-1,xEnd(grey)+2,yEnd(grey)+2)
88     img = img.crop(area)    
89     getWordsByBlank(img,path)
90  
91 def getWrods():
92     global wordslist
93     wordslist = getWordsList()
94     imgs = ["l1.png","l2.png","l3.png"]
95     for img in imgs:        
96         getWordsFormImg(img,'words/')
97      
98 if __name__ == "__main__":
99     getWrods()

  切出來的字的效果也很好的:

  

  自己對這圖像處理本來就不熟悉,用的都是土包子的方法。漢字的識別難度是比較大的,對應整齊的圖片,采樣DTW對字庫求相似項,效果還不錯,但用掃描儀、相機拍下來的文章切割處理后,效果很差。我用了BP神經網絡,但3500個漢字相當於3500個類,這個超多類別的分類問題,BP也很難應付,主要是訓練數據太少,手里只有一份字庫。

  如果您有什么好的方法識別圖片漢字的方法,希望給與我分享,謝謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM