Skip to content

Commit b4a8e9f

Browse files
Robert Sachunskyfinkf
authored andcommitted
binarize: zoom wrt. DPI to avoid inverse edges (and gain speed) at high DPI
1 parent d5f9325 commit b4a8e9f

File tree

2 files changed

+44
-24
lines changed

2 files changed

+44
-24
lines changed

ocrd_cis/ocrd-tool.json

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"git_url": "https://github.com/cisocrgroup/ocrd_cis",
3-
"version": "0.0.10",
3+
"version": "0.1.0",
44
"tools": {
55
"ocrd-cis-ocropy-binarize": {
66
"executable": "ocrd-cis-ocropy-binarize",
@@ -53,6 +53,12 @@
5353
"description": "maximum pixel number for connected components to regard as noise (0 will deactivate denoising)",
5454
"default": 0
5555
},
56+
"dpi": {
57+
"type": "number",
58+
"format": "float",
59+
"description": "pixel density in dots per inch (overrides any meta-data in the images); disabled when zero or negative",
60+
"default": 0
61+
},
5662
"level-of-operation": {
5763
"type": "string",
5864
"enum": ["page", "region", "line"],
@@ -121,8 +127,8 @@
121127
"dpi": {
122128
"type": "number",
123129
"format": "float",
124-
"description": "pixel density in dots per inch (overrides any meta-data in the images); disabled when negative",
125-
"default": -1
130+
"description": "pixel density in dots per inch (overrides any meta-data in the images); disabled when zero or negative",
131+
"default": 0
126132
},
127133
"level-of-operation": {
128134
"type": "string",
@@ -160,8 +166,8 @@
160166
"dpi": {
161167
"type": "number",
162168
"format": "float",
163-
"description": "pixel density in dots per inch (overrides any meta-data in the images); disabled when negative",
164-
"default": -1
169+
"description": "pixel density in dots per inch (overrides any meta-data in the images); disabled when zero or negative",
170+
"default": 0
165171
},
166172
"min_fraction": {
167173
"type": "number",
@@ -190,8 +196,8 @@
190196
"dpi": {
191197
"type": "number",
192198
"format": "float",
193-
"description": "pixel density in dots per inch (overrides any meta-data in the images); disabled when negative",
194-
"default": -1
199+
"description": "pixel density in dots per inch (overrides any meta-data in the images); disabled when zero or negative",
200+
"default": 0
195201
},
196202
"min_fraction": {
197203
"type": "number",
@@ -226,8 +232,8 @@
226232
"dpi": {
227233
"type": "number",
228234
"format": "float",
229-
"description": "pixel density in dots per inch (overrides any meta-data in the images); disabled when negative",
230-
"default": -1
235+
"description": "pixel density in dots per inch (overrides any meta-data in the images); disabled when zero or negative",
236+
"default": 0
231237
},
232238
"range": {
233239
"type": "number",
@@ -314,8 +320,8 @@
314320
"dpi": {
315321
"type": "number",
316322
"format": "float",
317-
"description": "pixel density in dots per inch (overrides any meta-data in the images); disabled when negative; when disabled and no meta-data is found, 300 is assumed",
318-
"default": -1
323+
"description": "pixel density in dots per inch (overrides any meta-data in the images); disabled when zero or negative; when disabled and no meta-data is found, 300 is assumed",
324+
"default": 0
319325
},
320326
"level-of-operation": {
321327
"type": "string",

ocrd_cis/ocropy/binarize.py

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
TOOL = 'ocrd-cis-ocropy-binarize'
3434
LOG = getLogger('processor.OcropyBinarize')
3535

36-
def binarize(pil_image, method='ocropy', maxskew=2, threshold=0.5, nrm=False):
36+
def binarize(pil_image, method='ocropy', maxskew=2, threshold=0.5, nrm=False, zoom=1.0):
3737
LOG.debug('binarizing %dx%d image with method=%s', pil_image.width, pil_image.height, method)
3838
if method == 'none':
3939
# useful if the images are already binary,
@@ -42,7 +42,7 @@ def binarize(pil_image, method='ocropy', maxskew=2, threshold=0.5, nrm=False):
4242
elif method == 'ocropy':
4343
# parameter defaults from ocropy-nlbin:
4444
array = pil2array(pil_image)
45-
bin, angle = common.binarize(array, maxskew=maxskew, threshold=threshold, nrm=nrm)
45+
bin, angle = common.binarize(array, maxskew=maxskew, threshold=threshold, nrm=nrm, zoom=zoom)
4646
return array2pil(bin), angle
4747
# equivalent to ocropy, but without deskewing:
4848
# elif method == 'kraken':
@@ -129,11 +129,21 @@ def process(self):
129129
value=self.parameter[name])
130130
for name in self.parameter.keys()])]))
131131

132-
page_image, page_xywh, _ = self.workspace.image_from_page(
132+
page_image, page_xywh, page_image_info = self.workspace.image_from_page(
133133
page, page_id, feature_filter='binarized')
134+
if self.parameter['dpi'] > 0:
135+
zoom = 300.0/self.parameter['dpi']
136+
elif page_image_info.resolution != 1:
137+
dpi = page_image_info.resolution
138+
if page_image_info.resolutionUnit == 'cm':
139+
dpi *= 2.54
140+
LOG.info('Page "%s" uses %f DPI', page_id, dpi)
141+
zoom = 300.0/dpi
142+
else:
143+
zoom = 1
134144

135145
if level == 'page':
136-
self.process_page(page, page_image, page_xywh,
146+
self.process_page(page, page_image, page_xywh, zoom,
137147
input_file.pageId, file_id)
138148
else:
139149
regions = page.get_TextRegion() + (
@@ -144,7 +154,7 @@ def process(self):
144154
region_image, region_xywh = self.workspace.image_from_segment(
145155
region, page_image, page_xywh, feature_filter='binarized')
146156
if level == 'region':
147-
self.process_region(region, region_image, region_xywh,
157+
self.process_region(region, region_image, region_xywh, zoom,
148158
input_file.pageId, file_id + '_' + region.id)
149159
continue
150160
lines = region.get_TextLine()
@@ -153,7 +163,7 @@ def process(self):
153163
for line in lines:
154164
line_image, line_xywh = self.workspace.image_from_segment(
155165
line, region_image, region_xywh, feature_filter='binarized')
156-
self.process_line(line, line_image, line_xywh,
166+
self.process_line(line, line_image, line_xywh, zoom,
157167
input_file.pageId, region.id,
158168
file_id + '_' + region.id + '_' + line.id)
159169

@@ -169,7 +179,7 @@ def process(self):
169179
LOG.info('created file ID: %s, file_grp: %s, path: %s',
170180
file_id, self.output_file_grp, out.local_filename)
171181

172-
def process_page(self, page, page_image, page_xywh, page_id, file_id):
182+
def process_page(self, page, page_image, page_xywh, zoom, page_id, file_id):
173183
LOG.info("About to binarize page '%s'", page_id)
174184
features = page_xywh['features']
175185
if 'angle' in page_xywh and page_xywh['angle']:
@@ -182,7 +192,8 @@ def process_page(self, page, page_image, page_xywh, page_id, file_id):
182192
method=self.parameter['method'],
183193
maxskew=maxskew,
184194
threshold=self.parameter['threshold'],
185-
nrm=self.parameter['grayscale'])
195+
nrm=self.parameter['grayscale'],
196+
zoom=zoom)
186197
if angle:
187198
features += ',deskewed'
188199
page_xywh['angle'] = angle
@@ -213,7 +224,7 @@ def process_page(self, page, page_image, page_xywh, page_id, file_id):
213224
filename=file_path,
214225
comments=features))
215226

216-
def process_region(self, region, region_image, region_xywh, page_id, file_id):
227+
def process_region(self, region, region_image, region_xywh, zoom, page_id, file_id):
217228
LOG.info("About to binarize page '%s' region '%s'", page_id, region.id)
218229
features = region_xywh['features']
219230
if 'angle' in region_xywh and region_xywh['angle']:
@@ -222,12 +233,14 @@ def process_region(self, region, region_image, region_xywh, page_id, file_id):
222233
bin_image, _ = binarize(region_image,
223234
method=self.parameter['method'],
224235
maxskew=0,
225-
nrm=self.parameter['grayscale'])
236+
nrm=self.parameter['grayscale'],
237+
zoom=zoom)
226238
else:
227239
bin_image, angle = binarize(region_image,
228240
method=self.parameter['method'],
229241
maxskew=self.parameter['maxskew'],
230-
nrm=self.parameter['grayscale'])
242+
nrm=self.parameter['grayscale'],
243+
zoom=zoom)
231244
if angle:
232245
features += ',deskewed'
233246
region_xywh['angle'] = angle
@@ -258,14 +271,15 @@ def process_region(self, region, region_image, region_xywh, page_id, file_id):
258271
filename=file_path,
259272
comments=features))
260273

261-
def process_line(self, line, line_image, line_xywh, page_id, region_id, file_id):
274+
def process_line(self, line, line_image, line_xywh, zoom, page_id, region_id, file_id):
262275
LOG.info("About to binarize page '%s' region '%s' line '%s'",
263276
page_id, region_id, line.id)
264277
features = line_xywh['features']
265278
bin_image, angle = binarize(line_image,
266279
method=self.parameter['method'],
267280
maxskew=self.parameter['maxskew'],
268-
nrm=self.parameter['grayscale'])
281+
nrm=self.parameter['grayscale'],
282+
zoom=zoom)
269283
if angle:
270284
features += ',deskewed'
271285
# annotate angle in PAGE (to allow consumers of the AlternativeImage

0 commit comments

Comments
 (0)