Skip to content

fix: keep extracted text aligned with rotated PDF page images in hi_res - #17

Open
anurag6569201 wants to merge 1 commit into
qa/agent-unstructured-io-unstructured/pr-17-4367/basefrom
qa/agent-unstructured-io-unstructured/pr-17-4367/head
Open

anurag6569201 wants to merge 1 commit into
qa/agent-unstructured-io-unstructured/pr-17-4367/basefrom
qa/agent-unstructured-io-unstructured/pr-17-4367/head

Conversation

@anurag6569201

Copy link
Copy Markdown

Problem

On PDF pages with a non-zero /Rotate, the hi_res object-detection layer (which runs on the rendered page image) and the pdfminer-extracted text layer could end up in different coordinate frames, off by the page rotation. The merge then placed extracted text in the wrong locations, scattering it across the output.

Fix

unstructured-inference may rotate a rendered page image to make its dominant text upright and reports that angle as pdf_rotation_correction in the page image metadata. This change mirrors that same rotation onto the pdfminer-extracted coordinates so both layers share one coordinate frame and merge correctly.

  • _rotate_bboxes rotates bounding boxes to match PIL's rotate(angle, expand=True).
  • process_data_with_pdfminer / process_file_with_pdfminer accept a per-page rotation_corrections list and apply it to element coordinates and link bounding boxes.
  • partition_pdf reads pdf_rotation_correction from the inferred layout's image metadata and threads it into the pdfminer pass.

unstructured performs no orientation detection of its own — it simply mirrors the correction reported by the renderer, so the two layers stay aligned by construction.

Tests

  • Added a unit test for _rotate_bboxes covering the 0/90/180/270 directions, round-trip, and bbox validity.
  • Existing pdfminer processing tests pass unchanged.

Requires the paired unstructured-inference change that emits pdf_rotation_correction.

🤖 Generated with Claude Code


Summary by cubic

Keeps extracted text aligned with rotated PDF page images in hi_res by mirroring the renderer’s rotation onto pdfminer coordinates, fixing scattered text on pages with non-zero /Rotate.

  • Bug Fixes

    • Thread per-page rotation_corrections (from pdf_rotation_correction image metadata) through partition_pdf into process_*_with_pdfminer (file and data paths); rotate element coords and link bboxes to mirror PIL rotate(angle, expand=True).
    • Add _rotation_corrections_from_layout and _rotate_bboxes with tests covering default-to-0, pass-through into pdfminer, and 0/90/180/270 rotation behavior.
  • Dependencies

    • Bump unstructured-inference minimum to >=1.6.12 which emits pdf_rotation_correction.

Written for commit 6e7f122. Summary will update on new commits.

Review in cubic

Source merge-base: 19857c193657b5f1b0ca922562a3015b38cc6fb8
Source head: 6e7f1221a99c587451b0c80cf30b4b544e74757a

@shipwright-agent

Copy link
Copy Markdown

⛔ Shipwright · Blocked

Recommendation: do not merge PR #17 · Tier T3
Checks: 0 total · 0 needing attention

Next step: resolve the blocking findings before merge.

Findings (6)

  • CRITICAL The rotation correction is applied to layout.element_coords but not to the per-element coordinates used later in the merge path. · unstructured/partition/pdf_image/pdfminer_processing.py:600
    • Fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.
  • CRITICAL The rotation correction is indexed by page_number, but page_number is derived from pdfplumber page enumeration. · unstructured/partition/pdf_image/pdfminer_processing.py:592
    • Fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.
  • CRITICAL The rotation correction is applied to layout.element_coords but not to the per-element coordinates used later in the merge path. · unstructured/partition/pdf_image/pdfminer_processing.py:600
    • Fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.
  • HIGH The rotation correction is applied to layout.element_coords but not to the per-element coordinates used later in the merge path. · unstructured/partition/pdf_image/pdfminer_processing.py:600
    • Fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.
  • HIGH The rotation correction is applied to layout.element_coords but not to the per-element coordinates used later in the merge path. · unstructured/partition/pdf_image/pdfminer_processing.py:600
    • Fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.
  • HIGH The rotation correction is applied to layout.element_coords but not to the per-element coordinates used later in the merge path. · unstructured/partition/pdf_image/pdfminer_processing.py:600
    • Fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.

Fireworks usage: 29,680 input · 935 output · 30,615 total tokens · $0.0071 · 14s · 0 fix iteration(s)

Open the Shipwright check for full evidence and the audit bundle. Use /shipwright rerun to verify again.

angle = (
rotation_corrections[page_number]
if rotation_corrections is not None and page_number < len(rotation_corrections)
else 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · HIGH

The rotation correction is applied to layout.element_coords but not to the per-element coordinates used later in the merge path.

Impact: The rotation correction is applied to layout.element_coords but not to the per-element coordinates used later in the merge path. If merge_inferred_with_extracted_layout consumes element_coords from the pdfminer layout and compares them against the object-detection layer, the fix is incomplete for any element whose coordinates are stored or recomputed elsewhere. The diff only mutates layout.element_coords at pdfminer…

Suggested fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.

angle = (
rotation_corrections[page_number]
if rotation_corrections is not None and page_number < len(rotation_corrections)
else 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · HIGH

The rotation correction is applied to layout.element_coords but not to the per-element coordinates used later in the merge path.

Impact: The rotation correction is applied to layout.element_coords but not to the per-element coordinates used later in the merge path. If merge_inferred_with_extracted_layout consumes element_coords from the pdfminer layout and compares them against the object-detection layer, the fix is incomplete for any element whose coordinates are stored or recomputed elsewhere. The diff only mutates layout.element_coords at pdfminer…

Suggested fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.

angle = (
rotation_corrections[page_number]
if rotation_corrections is not None and page_number < len(rotation_corrections)
else 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · HIGH

The rotation correction is applied to layout.element_coords but not to the per-element coordinates used later in the merge path.

Impact: The rotation correction is applied to layout.element_coords but not to the per-element coordinates used later in the merge path. If merge_inferred_with_extracted_layout consumes element_coords from the pdfminer layout and compares them against the object-detection layer, the fix is incomplete for any element whose coordinates are stored or recomputed elsewhere. The diff only mutates layout.element_coords at pdfminer…

Suggested fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant