Skip to content

Commit a8dc700

Browse files
author
Robert Sachunsky
committed
resegment: subtract matching lines from non-matching lines
1 parent 895687f commit a8dc700

File tree

1 file changed

+35
-8
lines changed

1 file changed

+35
-8
lines changed

ocrd_cis/ocropy/resegment.py

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -180,16 +180,19 @@ def _process_segment(self, parent, parent_image, parent_coords, page_id, zoom, l
180180
try:
181181
if report:
182182
raise Exception(report)
183-
# draw.polygon: If any segment_polygon lies outside of parent
184-
# (causing negative/above-max indices), either fully or partially,
185-
# then this will silently ignore them. The caller does not need
186-
# to concern herself with this.
187183
# get existing line labels:
188184
line_labels = np.zeros_like(parent_bin, np.bool)
189185
line_labels = np.tile(np.expand_dims(line_labels, -1), (1,1,len(lines)))
186+
line_polygons = []
190187
for i, segment in enumerate(lines):
191188
segment_polygon = coordinates_of_segment(segment, parent_image, parent_coords)
192-
segment_polygon = np.array(make_valid(Polygon(segment_polygon)).buffer(margin).exterior, np.int)[:-1]
189+
segment_polygon = make_valid(Polygon(segment_polygon)).buffer(margin)
190+
line_polygons.append(prep(segment_polygon))
191+
segment_polygon = np.array(segment_polygon.exterior, np.int)[:-1]
192+
# draw.polygon: If any segment_polygon lies outside of parent
193+
# (causing negative/above-max indices), either fully or partially,
194+
# then this will silently ignore them. The caller does not need
195+
# to concern herself with this.
193196
segment_y, segment_x = draw.polygon(segment_polygon[:, 1],
194197
segment_polygon[:, 0],
195198
parent_bin.shape)
@@ -230,9 +233,6 @@ def _process_segment(self, parent, parent_image, parent_coords, page_id, zoom, l
230233
# DSAVE('new_line_labels', [new_line_labels, parent_bin], disabled=False)
231234
new_line_polygons = [make_valid(Polygon(line_poly))
232235
for line_label, line_poly in new_line_polygons]
233-
line_polygons = [prep(make_valid(Polygon(coordinates_of_segment(
234-
line, parent_image, parent_coords))).buffer(margin))
235-
for line in lines]
236236
# polygons for intersecting pairs
237237
intersections = dict()
238238
# ratio of overlap between intersection and new line
@@ -292,6 +292,7 @@ def _process_segment(self, parent, parent_image, parent_coords, page_id, zoom, l
292292
line.id, center.distance(new_center))
293293
assignments[i] = j
294294
# validate assignments retain enough area and do not loose unassigned matches
295+
line_polygons = [poly.context.buffer(-margin) for poly in line_polygons]
295296
for j, line in enumerate(lines):
296297
new_lines = np.nonzero(assignments == j)[0]
297298
if not np.prod(new_lines.shape):
@@ -322,6 +323,7 @@ def _process_segment(self, parent, parent_image, parent_coords, page_id, zoom, l
322323
LOG.debug("joining %d new line polygons for '%s'", len(new_lines), line.id)
323324
new_polygon = join_polygons([intersections[(i, j)] for i in new_lines],
324325
contract=scale//2)
326+
line_polygons[j] = new_polygon
325327
# convert back to absolute (page) coordinates:
326328
line_polygon = coordinates_for_segment(new_polygon.exterior.coords[:-1],
327329
parent_image, parent_coords)
@@ -331,6 +333,31 @@ def _process_segment(self, parent, parent_image, parent_coords, page_id, zoom, l
331333
return
332334
# annotate result:
333335
line.get_Coords().set_points(points_from_polygon(line_polygon))
336+
# now also ensure the assigned lines do not overlap other existing lines
337+
for i in new_lines:
338+
for otherj in np.nonzero(fits_fg[i] > 0.1)[0]:
339+
if j == otherj:
340+
continue
341+
otherline = lines[otherj]
342+
LOG.debug("subtracting new '%s' from overlapping '%s'", line.id, otherline.id)
343+
other_polygon = diff_polygons(line_polygons[otherj], new_polygon)
344+
# convert back to absolute (page) coordinates:
345+
other_polygon = coordinates_for_segment(other_polygon.exterior.coords[:-1],
346+
parent_image, parent_coords)
347+
other_polygon = polygon_for_parent(other_polygon, otherline.parent_object_)
348+
if other_polygon is None:
349+
LOG.warning("Ignoring extant new polygon for line '%s'", otherline.id)
350+
continue
351+
otherline.get_Coords().set_points(points_from_polygon(other_polygon))
352+
353+
def diff_polygons(poly1, poly2):
354+
poly = poly1.difference(poly2)
355+
if poly.type == 'MultiPolygon':
356+
poly = poly.convex_hull
357+
if poly.minimum_clearance < 1.0:
358+
poly = asPolygon(np.round(poly.exterior.coords))
359+
poly = make_valid(poly)
360+
return poly
334361

335362
def join_polygons(polygons, contract=2):
336363
# construct convex hull

0 commit comments

Comments
 (0)