@@ -180,16 +180,19 @@ def _process_segment(self, parent, parent_image, parent_coords, page_id, zoom, l
180
180
try :
181
181
if report :
182
182
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.
187
183
# get existing line labels:
188
184
line_labels = np .zeros_like (parent_bin , np .bool )
189
185
line_labels = np .tile (np .expand_dims (line_labels , - 1 ), (1 ,1 ,len (lines )))
186
+ line_polygons = []
190
187
for i , segment in enumerate (lines ):
191
188
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.
193
196
segment_y , segment_x = draw .polygon (segment_polygon [:, 1 ],
194
197
segment_polygon [:, 0 ],
195
198
parent_bin .shape )
@@ -230,9 +233,6 @@ def _process_segment(self, parent, parent_image, parent_coords, page_id, zoom, l
230
233
# DSAVE('new_line_labels', [new_line_labels, parent_bin], disabled=False)
231
234
new_line_polygons = [make_valid (Polygon (line_poly ))
232
235
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 ]
236
236
# polygons for intersecting pairs
237
237
intersections = dict ()
238
238
# 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
292
292
line .id , center .distance (new_center ))
293
293
assignments [i ] = j
294
294
# validate assignments retain enough area and do not loose unassigned matches
295
+ line_polygons = [poly .context .buffer (- margin ) for poly in line_polygons ]
295
296
for j , line in enumerate (lines ):
296
297
new_lines = np .nonzero (assignments == j )[0 ]
297
298
if not np .prod (new_lines .shape ):
@@ -322,6 +323,7 @@ def _process_segment(self, parent, parent_image, parent_coords, page_id, zoom, l
322
323
LOG .debug ("joining %d new line polygons for '%s'" , len (new_lines ), line .id )
323
324
new_polygon = join_polygons ([intersections [(i , j )] for i in new_lines ],
324
325
contract = scale // 2 )
326
+ line_polygons [j ] = new_polygon
325
327
# convert back to absolute (page) coordinates:
326
328
line_polygon = coordinates_for_segment (new_polygon .exterior .coords [:- 1 ],
327
329
parent_image , parent_coords )
@@ -331,6 +333,31 @@ def _process_segment(self, parent, parent_image, parent_coords, page_id, zoom, l
331
333
return
332
334
# annotate result:
333
335
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
334
361
335
362
def join_polygons (polygons , contract = 2 ):
336
363
# construct convex hull
0 commit comments