Tesseract には確かにフォントサイズを取得する API がありますが、残念ながら pyocr では対応していないようですね。そのままでは取得できません。
仕方ないので、 OCR ツールとして tessaract
CLI コマンドを用いるとして次のようなモンキーパッチを当ててみたところ、手元の環境では追加でフォントサイズも取得できるようになりました。尚、 tesseract
CLI コマンドからフォントサイズを要求するオプションを使用するには、 Tesseract 3.04.00 以降が必要です。
python
1 import re
2 import PIL . Image
3 import pyocr
4
5
6 class _WordHTMLParserWithFontAttr ( pyocr . builders . _WordHTMLParser ) :
7 '''
8 Tesseract hOCR parser with support for x_fsize additional attribute.
9 '''
10 def __init__ ( self ) :
11 super ( _WordHTMLParserWithFontAttr , self ) . __init__ ( )
12
13 self . _last_box = None
14 self . _re_fsize = re . compile ( r'(^|;)\s*x_fsize\s+(?P<fsize>\d+)' )
15 self . __current_fsize = None
16
17 def handle_starttag ( self , tag , attrs ) :
18 super ( _WordHTMLParserWithFontAttr , self ) . handle_starttag ( tag , attrs )
19
20 # Memorize `x_fsize` attribute if found
21 if tag != 'span' :
22 return
23
24 title = None
25 tag_type = None
26
27 for attr in attrs :
28 if attr [ 0 ] == 'class' :
29 tag_type = attr [ 1 ]
30 if attr [ 0 ] == 'title' :
31 title = attr [ 1 ]
32
33 if title is not None and tag_type in ( 'ocr_word' , 'ocrx_word' ) :
34 self . __current_fsize = None
35 m = self . _re_fsize . search ( title )
36
37 if m :
38 self . __current_fsize = int ( m . group ( 'fsize' ) )
39
40 def handle_endtag ( self , tag ) :
41 super ( _WordHTMLParserWithFontAttr , self ) . handle_endtag ( tag )
42
43 if len ( self . boxes ) > 0 and self . boxes [ - 1 ] != self . _last_box :
44 self . _last_box = self . boxes [ - 1 ]
45 self . _last_box . fsize = self . __current_fsize
46
47
48 class WordBoxBuilderWithFontAttr ( pyocr . builders . WordBoxBuilder ) :
49 '''
50 Builder with support for `hocr_font_info` on Tesseract 3.04 and 3.05.
51 '''
52 def __init__ ( self , tesseract_layout = 1 ) :
53 super ( WordBoxBuilderWithFontAttr , self ) . __init__ (
54 tesseract_layout = tesseract_layout
55 )
56
57 # Requires tesseract >= 3.04.00
58 self . tesseract_configs += [ '-c' , 'hocr_font_info=1' ]
59
60 def read_file ( self , file_descriptor ) :
61 '''
62 Same as WordBoxBuilder.read_file, except for using parser class.
63 '''
64 parser = _WordHTMLParserWithFontAttr ( )
65 html_str = file_descriptor . read ( )
66 parser . feed ( html_str )
67
68 if len ( parser . boxes ) > 0 :
69 last_box = parser . boxes [ - 1 ]
70
71 if last_box . content == pyocr . builders . to_unicode ( '' ) :
72 # some parser leave an empty box at the end
73 parser . boxes . pop ( - 1 )
74
75 return parser . boxes
76
77 return [ ]
78
79
80 image = PIL . Image . open ( 'sample.png' )
81 builder = WordBoxBuilderWithFontAttr ( )
82 boxes = pyocr . tesseract . image_to_string ( image , lang = 'jpn+eng' , builder = builder )
83
84 for box in boxes :
85 print (
86 '"%s": at %d, %d (%d x %d) / fsize=%d' % (
87 box . content ,
88 box . position [ 0 ] [ 0 ] ,
89 box . position [ 0 ] [ 1 ] ,
90 box . position [ 1 ] [ 0 ] - box . position [ 0 ] [ 0 ] ,
91 box . position [ 1 ] [ 1 ] - box . position [ 0 ] [ 1 ] ,
92 box . fsize ,
93 )
94 )
ただ、さらに残念なことに、同様のコードは (まだ alpha 版ですが) 最新の Tesseract 4.00.00alpha では動作しません。異常な値のフォントサイズが返されます。これは、 4.00 で採用されている LSTM ベースの OCR エンジンがフォント認識に対応していないため だそうで、今後対応するかどうかも不透明なようです。
そういった将来的な互換性のことも考えると、もしかすると変なパッチを当てて無理やり使うよりは、単に認識された box の高さ (前掲のコード同様に、標準の pyocr.builders.WordBoxBuilder
を使えば position
から計算できます) をフォントサイズの代わりとして使用した方が良いのかもしれません。そのあたりは適宜ご自身でご判断下さい。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/05/17 06:04