Skip to content

fix(ocr): restore OCR of scanned pages only with page_bitmap_area_threshold - #4999

Open
yashikam19 wants to merge 4 commits into
docling-project:mainfrom
yashikam19:fix/ocr-bitmap-area-threshold
Open

yashikam19 wants to merge 4 commits into
docling-project:mainfrom
yashikam19:fix/ocr-bitmap-area-threshold

Conversation

@yashikam19

@yashikam19 yashikam19 commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Since #3710 (2.116.0), bitmap_area_threshold raises a ValidationError, also with do_ocr=False. No OcrMode can replace it: FULL_PAGE OCRs every page, and DEFAULT OCRs every cluster that touches a bitmap, so pages with only logos or photos still get OCR.

This PR adds OcrOptions.page_bitmap_area_threshold (off by default). A page is OCRed only when bitmaps cover at least that fraction of it. Other pages skip OCR and keep their native text, whatever the mode.

TesseractCliOcrOptions(mode=OcrMode.FULL_PAGE, page_bitmap_area_threshold=0.97)
docling mixed.pdf --ocr-mode full_page --ocr-option page_bitmap_area_threshold=0.97

The change:

  • pipeline_options.py: the new field (float | None, 0.0-1.0). The old bitmap_area_threshold works again, in the constructor and on assignment, with a DeprecationWarning, as force_full_page_ocr does.
  • base_ocr_model.py: get_ocr_rects() returns no rects for a page below the threshold, so every engine supports it. In FULL_PAGE mode, a skipped page keeps its PDF line, word and char cells.
  • page_preprocessing_model.py: in FULL_PAGE mode, native text is still extracted when the threshold is set.
  • auto_ocr_model.py: OcrAutoModel passes the field to the engine it selects.
  • Docs: a new section in docs/concepts/OCR.md and an example in the usage skill.

Issue resolved by this Pull Request:
Resolves #4834

Checklist:

  • Documentation has been updated, if necessary.
  • Examples have been added, if necessary.
  • Tests have been added, if necessary.

Review evidence:

  • Before and after, on a 3-page PDF made from test files, with Tesseract:

    page bitmaps main, FULL_PAGE main, DEFAULT this branch, FULL_PAGE + 0.97
    2206.01062.pdf p1, programmatic 1% full-page OCR OCR of 16% of the page no OCR, native text
    picture_classification.pdf p1, pictures 15% full-page OCR OCR of 17% of the page no OCR, native text
    ocr_test.pdf p1, scan 100% full-page OCR OCR of 8% of the page full-page OCR

    The old bitmap_area_threshold=0.97 gives the last column, with the warning.

  • Reference data: no change. The option is off by default.

  • Tests: tests/test_ocr_page_bitmap_area_threshold.py (13 tests, real PDFs, default backend) covers the deprecated field (constructor, assignment, warning shown at the caller's line), pages above and below the threshold, and native lines, words and chars kept in FULL_PAGE mode.

  • Commands: uv run pytest on the new tests and the OCR option, rect and cell tests: 207 passed. make validate: passed.

  • Scope:

    • The old field sets only the threshold, not the mode. To OCR scans in full, as before OcrMode, also set mode=OcrMode.FULL_PAGE.
    • Saved configs from before 2.116.0 contain bitmap_area_threshold: 0.05. They now skip OCR on pages with less than 5% bitmaps, as they did then.
    • No test covers the OcrAutoModel change, because it would load a real OCR engine.

…eshold

Since docling-project#3710, `bitmap_area_threshold` raises a ValidationError, and no OcrMode can skip OCR on pages that carry only small bitmaps.

Add `OcrOptions.page_bitmap_area_threshold`: a page is OCRed only when bitmaps cover at least that fraction of it. The pages below it keep their native text, also in FULL_PAGE mode. Accept `bitmap_area_threshold` as a deprecated alias, and pass the field on from OcrAutoOptions.

Resolves docling-project#4834

Signed-off-by: Yashika Malhotra <106444881+yashikam19@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor

✅ DCO Check Passed

Thanks @yashikam19, all your commits are properly signed off. 🎉

@mergify

mergify Bot commented Oct 24, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

🟢 Merge protection satisfied — ready to merge.

Show 1 satisfied protection

🟢 Enforce conventional commit

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|docs|style|refactor|perf|test|build|ci|chore|revert)(?:\(.+\))?(!)?:

@github-actions github-actions Bot added ai:ci-safe AI triage found no CI-safety concern (advisory) bug Something isn't working ocr labels Oct 24, 2026
@github-actions

github-actions Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

AI triage (advisory)

Checked commit dc3c8309c6. The analysis read the diff only. It did not run code from this pull request.

This pull request adds page_bitmap_area_threshold to OcrOptions. Pages with bitmap coverage below this threshold skip OCR and keep their native text.

CI safety: no concern found. A maintainer must still approve CI.

2 related pull request(s) in the same code
PR State Signal Assessment
#4654 open changes the same code related: PR #4654 touches OCR options and models to replace broken text layers with OCR, but it does not add page bitmap area filtering.
#3710 merged referenced as #3710 related: PR #3710 introduced OCR modes and removed the previous bitmap_area_threshold, which this pull request restores as page_bitmap_area_threshold.

The ai:* labels are advisory. They do not approve CI and they do not add tests:full. A new push runs this check again.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AI first review (advisory): blocker found

This review covers the full diff at cb2853c283. It read the code and did not run it.

The PR adds page_bitmap_area_threshold to skip OCR on pages with low bitmap coverage. When mode=OcrMode.FULL_PAGE is used, post_process_cells deletes native word_cells and char_cells on pages that skip OCR.

A maintainer makes the merge decision. This review never approves the pull request.

Comment thread docling/models/base_ocr_model.py Outdated
@github-actions github-actions Bot added the ai:review-changes AI first review suggests changes label Oct 24, 2026
…eshold

In FULL_PAGE mode, post_process_cells removed every word and char cell that is not from OCR, also on a page that page_bitmap_area_threshold kept from OCR. Filter them only when full-page OCR ran on the page.

Test with the default docling-parse backend, which gives word cells.

Signed-off-by: Yashika Malhotra <106444881+yashikam19@users.noreply.github.com>
@github-actions github-actions Bot added ai:ci-safe AI triage found no CI-safety concern (advisory) and removed ai:ci-safe AI triage found no CI-safety concern (advisory) ai:review-changes AI first review suggests changes labels Oct 24, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AI first review (advisory): no blocker found

This review covers the changes since cb2853c283 at 07260b0df9. It read the code and did not run it.

I found no blocking defect in the update. The earlier blocker is fixed: post_process_cells now filters word and char cells only when OCR ran on the page. I could not check the real-PDF coverage values that the tests rely on (full coverage for ocr_test.pdf, about 15% for picture_classification.pdf).

Earlier findings

  • fixed (blocker): FULL_PAGE mode clears native word and character cells on skipped pages

A maintainer makes the merge decision. This review never approves the pull request.

@github-actions github-actions Bot added the ai:review-lgtm AI first review found no blocker or major issue (advisory) label Oct 24, 2026
…ning

Code written before OcrMode also set bitmap_area_threshold on a built options object, which still raised a ValidationError. Add a deprecated property that sets page_bitmap_area_threshold. It stays out of dumps.

Point the deprecation warning at the caller. Python hides a DeprecationWarning that points to library code, so users did not see it.

Signed-off-by: Yashika Malhotra <106444881+yashikam19@users.noreply.github.com>
@github-actions github-actions Bot added ai:ci-safe AI triage found no CI-safety concern (advisory) and removed ai:ci-safe AI triage found no CI-safety concern (advisory) ai:review-lgtm AI first review found no blocker or major issue (advisory) labels Oct 24, 2026
@codecov

codecov Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.87179% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
docling/datamodel/pipeline_options.py 89.47% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

The page_bitmap_area_threshold key widens the Key column, which cannot
wrap, so at 80 columns the Type column cut enum choices such as
[tiny|small|medium]. Fold long values instead, and give the test a wide
console: the rich console reads its width at import, so terminal_width
did not apply.

Signed-off-by: Yashika Malhotra <106444881+yashikam19@users.noreply.github.com>
@github-actions github-actions Bot added ai:ci-safe AI triage found no CI-safety concern (advisory) and removed ai:ci-safe AI triage found no CI-safety concern (advisory) labels Oct 25, 2026

This branch has not been deployed

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

Labels

ai:ci-safe AI triage found no CI-safety concern (advisory) bug Something isn't working ocr

Projects

None yet

Development

Successfully merging this pull request may close these issues.

No way to restrict OCR to scanned pages since bitmap_area_threshold removal (#3710)

1 participant