Detect and join rectangles of "connected" vector graphics.
(npaths=None)
| 2296 | return False |
| 2297 | |
| 2298 | def clean_graphics(npaths=None): |
| 2299 | """Detect and join rectangles of "connected" vector graphics.""" |
| 2300 | if npaths is None: |
| 2301 | allpaths = page.get_drawings() |
| 2302 | else: # accept passed-in vector graphics |
| 2303 | allpaths = npaths[:] # paths relevant for table detection |
| 2304 | paths = [] |
| 2305 | for p in allpaths: |
| 2306 | # If only looking at lines, we ignore fill-only paths, |
| 2307 | # except simulated lines (i.e. small width or height). |
| 2308 | if ( |
| 2309 | lines_strict |
| 2310 | and p["type"] == "f" |
| 2311 | and p["rect"].width > snap_x |
| 2312 | and p["rect"].height > snap_y |
| 2313 | ): |
| 2314 | continue |
| 2315 | paths.append(p) |
| 2316 | |
| 2317 | # start with all vector graphics rectangles |
| 2318 | prects = sorted(set([p["rect"] for p in paths]), key=lambda r: (r.y1, r.x0)) |
| 2319 | new_rects = [] # the final list of joined rectangles |
| 2320 | # ---------------------------------------------------------------- |
| 2321 | # Strategy: Join rectangles that "almost touch" each other. |
| 2322 | # Extend first rectangle with any other that is a "neighbor". |
| 2323 | # Then move it to the final list and continue with the rest. |
| 2324 | # ---------------------------------------------------------------- |
| 2325 | while prects: # the algorithm will empty this list |
| 2326 | prect0 = prects[0] # copy of first rectangle (performance reasons!) |
| 2327 | repeat = True |
| 2328 | while repeat: # this loop extends first rect in list |
| 2329 | repeat = False # set to true again if some other rect touches |
| 2330 | for i in range(len(prects) - 1, 0, -1): # run backwards |
| 2331 | if are_neighbors(prect0, prects[i]): # close enough to rect 0? |
| 2332 | prect0 |= prects[i].tl # extend rect 0 |
| 2333 | prect0 |= prects[i].br # extend rect 0 |
| 2334 | del prects[i] # delete this rect |
| 2335 | repeat = True # keep checking the rest |
| 2336 | |
| 2337 | # move rect 0 over to result list if there is some text in it |
| 2338 | if chars_in_rect(CHARS, prect0): |
| 2339 | # contains text, so accept it as a table bbox candidate |
| 2340 | new_rects.append(prect0) |
| 2341 | del prects[0] # remove from rect list |
| 2342 | |
| 2343 | return new_rects, paths |
| 2344 | |
| 2345 | bboxes, paths = clean_graphics(npaths=paths) |
| 2346 |
no test coverage detected
searching dependent graphs…