Skip to content

Commit bc41819

Browse files
committed
v1.3.1
1 parent ef469bf commit bc41819

File tree

6 files changed

+247
-13
lines changed

6 files changed

+247
-13
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ Ready-to-use OCR with 80+ [supported languages](https://www.jaided.ai/easyocr) a
1111
[Try Demo on our website](https://www.jaided.ai/easyocr)
1212

1313
## What's new
14+
- 20 April 2021 - Version 1.3.1
15+
- Add support for PIL image (thanks [@prays](https://github.com/prays))
16+
- Update argument setting for command line
17+
- Add `x_ths` and `y_ths` to control merging behavior when `paragraph=True`
1418
- 21 March 2021 - Version 1.3
1519
- Second-generation models: multiple times smaller size, multiple times faster inference, additional characters, comparable accuracy to the first generation models.
1620
EasyOCR will choose the latest model by default but you can also specify which model to use by passing `recog_network` argument when creating `Reader` instance.

easyocr/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
from .easyocr import Reader
22

3-
__version__ = '1.3.0.1'
3+
__version__ = '1.3.1'

easyocr/cli.py

Lines changed: 232 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,110 @@ def parse_args():
1212
type=str,
1313
help="for languages",
1414
)
15+
parser.add_argument(
16+
"--gpu",
17+
type=bool,
18+
choices=[True, False],
19+
default=True,
20+
help="Using GPU (default: True)",
21+
)
22+
parser.add_argument(
23+
"--model_storage_directory",
24+
type=str,
25+
default=None,
26+
help="Directory for model (.pth) file",
27+
)
28+
parser.add_argument(
29+
"--user_network_directory",
30+
type=str,
31+
default=None,
32+
help="Directory for custom network files",
33+
)
34+
parser.add_argument(
35+
"--recog_network",
36+
type=str,
37+
default='standard',
38+
help="Recognition networks",
39+
)
40+
parser.add_argument(
41+
"--download_enabled",
42+
type=bool,
43+
choices=[True, False],
44+
default=True,
45+
help="Enable Download",
46+
)
47+
parser.add_argument(
48+
"--detector",
49+
type=bool,
50+
choices=[True, False],
51+
default=True,
52+
help="Initialize text detector module",
53+
)
54+
parser.add_argument(
55+
"--recognizer",
56+
type=bool,
57+
choices=[True, False],
58+
default=True,
59+
help="Initialize text recognizer module",
60+
)
61+
parser.add_argument(
62+
"--verbose",
63+
type=bool,
64+
choices=[True, False],
65+
default=True,
66+
help="Print detail/warning",
67+
)
68+
parser.add_argument(
69+
"--quantize",
70+
type=bool,
71+
choices=[True, False],
72+
default=True,
73+
help="Use dynamic quantization",
74+
)
1575
parser.add_argument(
1676
"-f",
1777
"--file",
1878
required=True,
1979
type=str,
2080
help="input file",
2181
)
82+
parser.add_argument(
83+
"--decoder",
84+
type=str,
85+
choices=["greedy", 'beamsearch', 'wordbeamsearch'],
86+
default='greedy',
87+
help="decoder algorithm",
88+
)
89+
parser.add_argument(
90+
"--beamWidth",
91+
type=int,
92+
default=5,
93+
help="size of beam search",
94+
)
95+
parser.add_argument(
96+
"--batch_size",
97+
type=int,
98+
default=1,
99+
help="batch_size",
100+
)
101+
parser.add_argument(
102+
"--workers",
103+
type=int,
104+
default=0,
105+
help="number of processing cpu cores",
106+
)
107+
parser.add_argument(
108+
"--allowlist",
109+
type=str,
110+
default=None,
111+
help="Force EasyOCR to recognize only subset of characters",
112+
)
113+
parser.add_argument(
114+
"--blocklist",
115+
type=str,
116+
default=None,
117+
help="Block subset of character. This argument will be ignored if allowlist is given.",
118+
)
22119
parser.add_argument(
23120
"--detail",
24121
type=int,
@@ -27,20 +124,150 @@ def parse_args():
27124
help="simple output (default: 1)",
28125
)
29126
parser.add_argument(
30-
"--gpu",
127+
"--rotation_info",
128+
type=list,
129+
default=None,
130+
help="Allow EasyOCR to rotate each text box and return the one with the best confident score. Eligible values are 90, 180 and 270. For example, try [90, 180 ,270] for all possible text orientations.",
131+
)
132+
parser.add_argument(
133+
"--paragraph",
31134
type=bool,
32135
choices=[True, False],
33-
default=True,
34-
help="Using GPU (default: True)",
136+
default=False,
137+
help="Combine result into paragraph",
138+
)
139+
parser.add_argument(
140+
"--min_size",
141+
type=int,
142+
default=20,
143+
help="Filter text box smaller than minimum value in pixel",
144+
)
145+
parser.add_argument(
146+
"--contrast_ths",
147+
type=float,
148+
default=0.1,
149+
help="Text box with contrast lower than this value will be passed into model 2 times. First is with original image and second with contrast adjusted to 'adjust_contrast' value. The one with more confident level will be returned as a result.",
150+
)
151+
parser.add_argument(
152+
"--adjust_contrast",
153+
type=float,
154+
default=0.5,
155+
help="target contrast level for low contrast text box",
156+
)
157+
parser.add_argument(
158+
"--text_threshold",
159+
type=float,
160+
default=0.7,
161+
help="Text confidence threshold",
35162
)
163+
parser.add_argument(
164+
"--low_text",
165+
type=float,
166+
default=0.4,
167+
help="Text low-bound score",
168+
)
169+
parser.add_argument(
170+
"--link_threshold",
171+
type=float,
172+
default=0.4,
173+
help="Link confidence threshold",
174+
)
175+
parser.add_argument(
176+
"--canvas_size",
177+
type=int,
178+
default=2560,
179+
help="Maximum image size. Image bigger than this value will be resized down.",
180+
)
181+
parser.add_argument(
182+
"--mag_ratio",
183+
type=float,
184+
default=1.,
185+
help="Image magnification ratio",
186+
)
187+
parser.add_argument(
188+
"--slope_ths",
189+
type=float,
190+
default=0.1,
191+
help="Maximum slope (delta y/delta x) to considered merging. Low value means tiled boxes will not be merged.",
192+
)
193+
parser.add_argument(
194+
"--ycenter_ths",
195+
type=float,
196+
default=0.5,
197+
help="Maximum shift in y direction. Boxes with different level should not be merged.",
198+
)
199+
parser.add_argument(
200+
"--height_ths",
201+
type=float,
202+
default=0.5,
203+
help="Maximum different in box height. Boxes with very different text size should not be merged. ",
204+
)
205+
parser.add_argument(
206+
"--width_ths",
207+
type=float,
208+
default=0.5,
209+
help="Maximum horizontal distance to merge boxes.",
210+
)
211+
parser.add_argument(
212+
"--y_ths",
213+
type=float,
214+
default=0.5,
215+
help="Maximum horizontal distance to merge boxes (when paragraph = True).",
216+
)
217+
parser.add_argument(
218+
"--x_ths",
219+
type=float,
220+
default=1.0,
221+
help="Maximum horizontal distance to merge boxes (when paragraph = True).",
222+
)
223+
parser.add_argument(
224+
"--add_margin",
225+
type=float,
226+
default=0.1,
227+
help="Extend bounding boxes in all direction by certain value. This is important for language with complex script (E.g. Thai).",
228+
)
229+
36230
args = parser.parse_args()
37231
return args
38232

39233

40234
def main():
41235
args = parse_args()
42-
reader = easyocr.Reader(lang_list=args.lang, gpu=args.gpu)
43-
for line in reader.readtext(args.file, detail=args.detail):
236+
reader = easyocr.Reader(lang_list=args.lang,\
237+
gpu=args.gpu,\
238+
model_storage_directory=args.model_storage_directory,\
239+
user_network_directory=args.user_network_directory,\
240+
recog_network=args.recog_network,\
241+
download_enabled=args.download_enabled,\
242+
detector=args.detector,\
243+
recognizer=args.recognizer,\
244+
verbose=args.verbose,\
245+
quantize=args.quantize)
246+
for line in reader.readtext(args.file,\
247+
decoder=args.decoder,\
248+
beamWidth=args.beamWidth,\
249+
batch_size=args.batch_size,\
250+
workers=args.workers,\
251+
allowlist=args.allowlist,\
252+
blocklist=args.blocklist,\
253+
detail=args.detail,\
254+
rotation_info=args.rotation_info,\
255+
paragraph=args.paragraph,\
256+
min_size=args.min_size,\
257+
contrast_ths=args.contrast_ths,\
258+
adjust_contrast=args.adjust_contrast,\
259+
text_threshold=args.text_threshold,\
260+
low_text=args.low_text,\
261+
link_threshold=args.link_threshold,\
262+
canvas_size=args.canvas_size,\
263+
mag_ratio=args.mag_ratio,\
264+
slope_ths=args.slope_ths,\
265+
ycenter_ths=args.ycenter_ths,\
266+
height_ths=args.height_ths,\
267+
width_ths=args.width_ths,\
268+
y_ths=args.y_ths,\
269+
x_ths=args.x_ths,\
270+
add_margin=args.add_margin):
44271
print(line)
45272

46273

easyocr/easyocr.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -285,10 +285,9 @@ def detect(self, img, min_size = 20, text_threshold = 0.7, low_text = 0.4,\
285285
def recognize(self, img_cv_grey, horizontal_list=None, free_list=None,\
286286
decoder = 'greedy', beamWidth= 5, batch_size = 1,\
287287
workers = 0, allowlist = None, blocklist = None, detail = 1,\
288-
rotation_info = None,\
289-
paragraph = False,\
288+
rotation_info = None,paragraph = False,\
290289
contrast_ths = 0.1,adjust_contrast = 0.5, filter_ths = 0.003,\
291-
reformat=True):
290+
y_ths = 0.5, x_ths = 1.0, reformat=True):
292291

293292
if reformat:
294293
img, img_cv_grey = reformat_input(img_cv_grey)
@@ -350,7 +349,7 @@ def recognize(self, img_cv_grey, horizontal_list=None, free_list=None,\
350349
direction_mode = 'ltr'
351350

352351
if paragraph:
353-
result = get_paragraph(result, mode = direction_mode)
352+
result = get_paragraph(result, x_ths=x_ths, y_ths=y_ths, mode = direction_mode)
354353

355354
if detail == 0:
356355
return [item[1] for item in result]
@@ -364,7 +363,7 @@ def readtext(self, image, decoder = 'greedy', beamWidth= 5, batch_size = 1,\
364363
text_threshold = 0.7, low_text = 0.4, link_threshold = 0.4,\
365364
canvas_size = 2560, mag_ratio = 1.,\
366365
slope_ths = 0.1, ycenter_ths = 0.5, height_ths = 0.5,\
367-
width_ths = 0.5, add_margin = 0.1):
366+
width_ths = 0.5, y_ths = 0.5, x_ths = 1.0, add_margin = 0.1):
368367
'''
369368
Parameters:
370369
image: file path or numpy-array or a byte stream object
@@ -382,6 +381,6 @@ def readtext(self, image, decoder = 'greedy', beamWidth= 5, batch_size = 1,\
382381
decoder, beamWidth, batch_size,\
383382
workers, allowlist, blocklist, detail, rotation_info,\
384383
paragraph, contrast_ths, adjust_contrast,\
385-
filter_ths, False)
384+
filter_ths, y_ths, x_ths, False)
386385

387386
return result

releasenotes.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
- 20 April 2021 - Version 1.3.1
2+
- Add support for PIL image (thanks [@prays](https://github.com/prays))
3+
- Update argument setting for command line
4+
- Add `x_ths` and `y_ths` to control merging behavior when `paragraph=True`
15
- 21 March 2021 - Version 1.3
26
- Second-generation models: multiple times smaller size, multiple times faster inference, additional characters, comparable accuracy to the first generation models.
37
EasyOCR will choose the latest model by default but you can also specify which model to use by passing `recog_network` argument when creating `Reader` instance.

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def readme():
1717
name='easyocr',
1818
packages=['easyocr'],
1919
include_package_data=True,
20-
version='1.3.0.1',
20+
version='1.3.1',
2121
install_requires=requirements,
2222
entry_points={"console_scripts": ["easyocr= easyocr.cli:main"]},
2323
license='Apache License 2.0',

0 commit comments

Comments
 (0)