Reza2kn's picture
Final Rizeh reader INT4 conversions; source 51b8c314b055; full-page qualification limits documented
618450b verified
Raw History Blame Contribute Delete
1.44 kB
import math
import numpy as np
def _percentiles(b: np.ndarray, qs=(0.02, 0.5, 0.98)) -> list[float]:
"""np.percentile(b, 100 * qs) (linear) of a uint8 array, from its histogram:
no sort of the pixels."""
n = b.size
cum = np.cumsum(np.bincount(b.ravel(), minlength=256))
out = []
for q in qs:
x = q * (n - 1)
i = math.floor(x)
g = x - i
lo = float(np.searchsorted(cum, i, side="right"))
hi = float(np.searchsorted(cum, min(i + 1, n - 1), side="right"))
d = hi - lo
# numpy's lerp: from the nearer end
out.append(hi - d * (1 - g) if g >= 0.5 else lo + d * g)
return out
def is_dark_line(gray: np.ndarray, box) -> bool:
"""Light text on a dark ground (a banner, a dark table head, a slide): the
ground (the median of the line box) lies nearer the dark end than the text
does, so the bright tail is the longer one. A shadowed line keeps dark text
on a dimmer ground. The recognizers read dark text on light paper, so a
light-on-dark line is read inverted."""
H, W = gray.shape
x0, y0, x1, y1 = (float(v) for v in box[:4])
b = gray[
max(0, int(y0)) : min(H, int(y1) + 1), max(0, int(x0)) : min(W, int(x1) + 1)
]
if not b.size:
return False
lo, med, hi = (
_percentiles(b) if b.dtype == np.uint8 else np.percentile(b, (2, 50, 98))
)
return bool(hi - med > 2 * (med - lo) + 8)