You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Feature]: Option to force grayscale output (contrast-preserving decolorization) #1699
Allow forcing color input to grayscale on output (drop color).
Archival-safety caveat: a naive luminance conversion (e.g. PIL convert('L')) can collapse distinct colors that share similar luminance, harming contrast and legibility — coloured text, highlights, stamps. Doing this properly needs a contrast-preserving decolorization algorithm (cf. cv2.decolor / Lu et al., "Real-time contrast preserving decolorization") so colours that map to similar gray stay distinguishable.
Constraint: implement this without a heavy dependency — we do not want to pull in something as large as OpenCV just for decolorization. We essentially want cv2.decolor's behaviour from a lightweight implementation (or make it an optional/plugin feature).
Current state: the rasterizer auto-selects the minimum colour depth a page needs but never forces colour→gray.
Hi! I’m working on this and have a focused implementation in progress.
The approach is the discrete linear method from Lu, Xu, and Jia’s “Real-time Contrast Preserving Decolorization”: evaluate the 66 convex RGB weightings (0.1 increments) against a fixed sample of color pairs using the bimodal contrast objective, then apply the selected mapping with Pillow. This adds no dependency.
I’m exposing it as --force-grayscale / force_grayscale=True. The conversion runs only on the visible rasterized page, after OCR input preparation, so the image sent to the OCR engine and the Tesseract cache remain unchanged. Existing grayscale pixels pass through unchanged, transparency is composited onto white paper, and DPI is preserved.
I’ll include focused algorithm, option-plumbing, and pipeline-order tests, along with documentation and runtime evidence. Happy to adjust the option name or integration point if you prefer a different public shape.
Activity
ikeago commentedon Oct 12, 2026
Hi! I’m working on this and have a focused implementation in progress.
The approach is the discrete linear method from Lu, Xu, and Jia’s “Real-time Contrast Preserving Decolorization”: evaluate the 66 convex RGB weightings (0.1 increments) against a fixed sample of color pairs using the bimodal contrast objective, then apply the selected mapping with Pillow. This adds no dependency.
I’m exposing it as
--force-grayscale/force_grayscale=True. The conversion runs only on the visible rasterized page, after OCR input preparation, so the image sent to the OCR engine and the Tesseract cache remain unchanged. Existing grayscale pixels pass through unchanged, transparency is composited onto white paper, and DPI is preserved.I’ll include focused algorithm, option-plumbing, and pipeline-order tests, along with documentation and runtime evidence. Happy to adjust the option name or integration point if you prefer a different public shape.