Skip to content

[io] Resolve rotated block geometries from lines read back from an export - #2181

Merged
felixdittrich92 merged 1 commit into
mindee:mainfrom
RaphaelFakhri:fix/block-rotated-geometry-from-dict
Oct 26, 2026
Merged

felixdittrich92 merged 1 commit into
mindee:mainfrom
RaphaelFakhri:fix/block-rotated-geometry-from-dict

Conversation

@RaphaelFakhri

Copy link
Copy Markdown
Contributor

Block.__init__ picks the box resolution from the type of the first line geometry: resolve_enclosing_rbbox when it is a np.ndarray, resolve_enclosing_bbox otherwise. A rotated line geometry read back with from_dict (from export() or a JSON file) is a nested list, so the 4 points go to resolve_enclosing_bbox, which returns a straight ((xmin, ymin), (xmax, ymax)) box.

Page.export() rebuilds the blocks in reading order without passing a geometry. As a result, the rotated block polygons of a page loaded from a dict (e.g. from an ocr_predictor(assume_straight_pages=False) result saved as JSON) become straight boxes in the next export.

Repro:

import json
import numpy as np
from doctr.io import Block, Line, Page, Word

# Rotated word geometry, as built by the DocumentBuilder when assume_straight_pages=False
polygon = ((0.1, 0.1), (0.4, 0.2), (0.35, 0.4), (0.05, 0.3))
word = Word("hello", 0.9, polygon, 0.9, {"value": 0, "confidence": None})
page = Page(np.zeros((10, 10, 3), dtype=np.uint8), [Block([Line([word])])], 0, (10, 10))
exported = json.loads(json.dumps(page.export()))
print(np.round(exported["blocks"][0]["geometry"], 3).tolist())
print(np.round(Page.from_dict(exported).export()["blocks"][0]["geometry"], 3).tolist())

Before: the first line prints the rotated polygon [[0.1, 0.1], [0.415, 0.205], [0.35, 0.4], [0.035, 0.295]], the second prints the straight box [[0.05, 0.1], [0.4, 0.4]].
After: both lines print the rotated polygon.

Changes:

  • detect rotated line geometries by their number of points (len(geometry) == 4), like Line.__init__ already does for words
  • add test_block_rotated_lines_from_dict (block built from a line loaded with from_dict, then a page export, JSON round trip and re-export); it fails without the fix

Checks: pytest tests/common (708 passed), ruff check, ruff format --check, mypy doctr/io/elements.py (no new errors).

Fixes #2180

@felixdittrich92 felixdittrich92 self-assigned this Oct 26, 2026
@felixdittrich92 felixdittrich92 added this to the 1.2.0 milestone Oct 26, 2026
@felixdittrich92 felixdittrich92 added type: bug Something isn't working module: io Related to doctr.io ext: tests Related to tests folder labels Oct 26, 2026
@codecov

codecov Bot commented Oct 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.69%. Comparing base (aa17f53) to head (f0beaaa).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2181   +/-   ##
=======================================
  Coverage   97.68%   97.69%           
=======================================
  Files         170      170           
  Lines       10744    10744           
=======================================
+ Hits        10495    10496    +1     
+ Misses        249      248    -1     
Flag Coverage Δ
unittests 97.69% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@felixdittrich92 felixdittrich92 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM @RaphaelFakhri Thanks 👍

@felixdittrich92
felixdittrich92 merged commit 4abce0e into mindee:main Oct 26, 2026
56 of 57 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ext: tests Related to tests folder module: io Related to doctr.io type: bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rotated block geometries become straight boxes after Page.from_dict + export()

2 participants