Engineering Journal
Pdf Processor
Pdf Processor

Distinguishing line art from tables in geometric PDF extraction

2026-07-03

TLDR

Geometry-based table detectors misidentify technical schematics and wiring diagrams as grid tables because wire runs consist of intersecting horizontal and vertical line segments. Filtering line art using diagonal segment counts fails due to curve polyline flattening and table border cap noise. Categorizing stroke provenance (tracking subpath origin types during vector reconciliation) reliably separates technical drawings from structural table borders without ML model weights.
Identification MethodSignal Metric EvaluatedWiring Diagram AccuracyBalance Sheet Table Accuracy
Diagonal Segment CounterSegment angle ($\Delta x \neq 0, \Delta y \neq 0$)Low (Fails on flattened polylines)Low (Mistakes cap fragments for figures)
Subpath Stroke ProvenanceSubpath origin (RECT vs FREE_PATH)100% (2,400 figure strokes found)100% (0 figure strokes found)

Problem statement: the vector drawing ambiguity trap

PDF documents expose visual content via three primitives: raster images, text runs, and vector path streams.

Because technical diagrams, schematics, logos, and tables are all drawn using vector path streams, naive table engines cluster all intersecting horizontal and vertical vector lines into grid tables.

[PDF Path Operators] ---> Intersecting H/V Segments ---> Naive Lattice Reconstructor ---> Phantom Table!

Technical architecture: subpath stroke provenance tagging

Step 1: subpath reconciliation tagging

During operator parsing (ctmAdapter.js), tag each emitted line segment with its parent subpath origin type:
// Path Reconciliation Pass: Tag emitted segments with subpath provenance
export function reconcileSubpathSegment(pathCommand, viewportTransform) {
  return {
    x1: pathCommand.x1,
    y1: pathCommand.y1,
    x2: pathCommand.x2,
    y2: pathCommand.y2,
    srcType: pathCommand.type, // RECTANGLE | FREE_PATH | POLYGON | DASH_RUN
    srcSegCount: pathCommand.subpathSegmentCount
  };
}

Step 2: figure stroke classification

Classify segments as figure evidence if they originate from complex multi-segment subpaths that do not form pure axis-aligned rectangle borders:
export function isFigureStroke(segment, epsilonPx = 4) {
  // Single-segment fragments (like table border caps) are ignored
  if (segment.srcSegCount <= 1) return false;

const dx = Math.abs(segment.x2 - segment.x1); const dy = Math.abs(segment.y2 - segment.y1);

const isCleanHorizontal = dy <= epsilonPx && dx > epsilonPx; const isCleanVertical = dx <= epsilonPx && dy > epsilonPx;

// Pure clean H/V grid lines are not figure evidence return !isCleanHorizontal && !isCleanVertical; }


Spatial figure region dilation & content isolation

Group figure strokes into spatial bounding regions to protect technical diagrams from table grid generators:

  1. Grid Hash Bucket Allocation: Index figure stroke midpoints into a $16\text{px}$ spatial hash grid.
  2. Dilation Pass: Dilate active hash cells by 1 cell radius and compute connected components.
  3. Bounding Region Bounding: Expand components to encompass all member stroke extents.
  4. Table Pool Removal: Remove figure-tagged vector segments from the table-detection pool.
  5. Canvas Crop Harvesting: Crop high-resolution canvas image renders matching figure bounding boxes for output assembly.
Rule of thumb: Use subpath stroke provenance rather than segment angle statistics to separate technical drawings from structural table grids.
Read this post in the full Engineering Journal →