ek.ocr#
OCR evaluation – ek’s first concrete instance, built on ocracy.
OCR is the noisiest special case of information extraction. This subpackage adds
the OCR-specific pieces on top of ek’s source-agnostic core:
ocracy_backend()/read_text()– a thin bridge that turnsocracy’s 16-engine fleet into animage -> OcrResultcallable. The dependency arrow is strict:ek -> ocracy(via theek[ocr]extra), never the reverse.ekcore depends only on theOcrResultshape (.text/.blocks/.mean_confidence), so the benchmark below evaluates anyimage -> OcrResultcallable –ocracyor your own.profile()– per-engine capability profiles (who emits real vs model-guessed geometry, who is calibrated, who yields table structure), distilled frommisc/docs/ek_01.ektreats these as claims to verify empirically.evaluate_ocr()/add_gold_item()– run a fleet over a gold corpus, score with CER/WER (globally accumulated), slice the report, and persist gold + results to thedolstores under~/.local/share/ek/.table_from_ocr()/has_table_structure()– recover the existingek.metrics.tables.Tablefrom anOcrResult(whose engine-specific tabledata lives only in
.raw/.markdown) so the table metrics (TEDS / GriTS) can score OCR table output uniformly. The per-engine extractor is injected/registered under the"table_parsers"namespace (open-closed); seeek.ocr.tables.
Heavy engine SDKs and credentials are never required to import this module; they
are checked at call time via ek.registry.check_requirements().
Functions
|
Return an |
|
Convenience: OCR an image and return just the recognized text string. |
|
Benchmark an OCR engine against a gold corpus. |
|
Add one gold example to the |
|
Capability profile for an engine id (a safe default if unknown). |
|
Extract a normalized |
|
Whether |
|
Resolve a table parser reference (a registered name or a callable) to a callable. |
|
Whether |
- ek.ocr.add_gold_item(key, image, reference_text, *, slice=None, rootdir=None, **extra)[source]#
Add one gold example to the
goldstore.- Parameters:
key (
str) – Unique id for the document.image (
Any) – An image reference the engine can read (path, URL, …). Stored as a reference, not bytes – gold stores hold references + the expected text.reference_text (
str) – The ground-truth transcription.slice (
Optional[str]) – Optional stratification label (doc type, language, scan quality, …).rootdir (
Optional[str]) – Override the data root (tests/ephemeral use).**extra (
Any) – Any additional metadata to store on the record.
- Return type:
- ek.ocr.engine_yields_tables(engine)[source]#
Whether
engine’s capability profile claims scoreable table structure.A convenience over
ek.ocr.profile(): returns the engine profile’stablesflag. ek treats the profile as a prior (Azure DI, AWS Textract, PaddleOCR and the markdown engines are expected to yield scoreable tables; Google Vision is not), to be verified empirically by actually runningtable_from_ocr(). Use it to skip table scoring for engines that cannot emit cells in the first place.- Return type:
- ek.ocr.evaluate_ocr(engine, gold, *, metric='cer', normalize=None, grammar=None, image_key='image', reference_key='reference_text', slice_key='slice', persist=False, run_id=None, rootdir=None)[source]#
Benchmark an OCR engine against a gold corpus.
- Parameters:
engine (
Union[str,Callable]) – Animage -> OcrResultcallable, or anocracybackend id.gold (
Mapping) – A mappingkey -> {image, reference_text, [slice], ...}– a plain dict or aekgold store.metric (
str) –"cer"(default) or"wer"(or any registered string metric).normalize (
Any) – Optional canonicalizer applied to both sides before scoring.grammar (
Any) – Optional Layer-A grammar (forwarded to the metric).image_key (
str) – Field names within each gold record.reference_key (
str) – Field names within each gold record.slice_key (
str) – Field names within each gold record.persist (
bool) – If true, write per-item results and the run aggregate to theresults/runsstores.run_id (
Optional[str]) – Identifier for this run (auto-generated from the clock if omitted).rootdir (
Optional[str]) – Override the data root (tests/ephemeral use).
- Returns:
A
Reportwhosedetail['per_item']maps each gold key to its prediction, reference, slice, score, and engine confidence/backend.
- ek.ocr.has_table_structure(ocr_result, *, parser=None)[source]#
Whether
table_from_ocr()recovers a non-empty table fromocr_result.A thin predicate over
table_from_ocr()(sameparsersemantics): true iff a table with at least one cell can be recovered. Use it to route an OCR result to the table metrics vs the text-only CER/WER fallback.- Return type:
- ek.ocr.ocracy_backend(backend=None, **default_kwargs)[source]#
Return an
image -> OcrResultcallable bound to oneocracybackend.- Parameters:
- Return type:
- Returns:
A callable suitable for
ek.ocr.evaluate_ocr().
- ek.ocr.profile(engine)[source]#
Capability profile for an engine id (a safe default if unknown).
Accepts
ocracy’s canonical hyphenated ids and their underscore variants.- Return type:
- ek.ocr.read_text(image, *, backend=None, **kwargs)[source]#
Convenience: OCR an image and return just the recognized text string.
- Return type:
- ek.ocr.resolve_table_parser(ref)[source]#
Resolve a table parser reference (a registered name or a callable) to a callable.
Mirrors how other ek strategies resolve from the registry (see
ek.registry.resolve()). Astris looked up under the"table_parsers"namespace; an already-callable parser is returned unchanged.
- ek.ocr.table_from_ocr(ocr_result, *, parser=None)[source]#
Extract a normalized
Tablefrom anOcrResult.The single seam ek’s table metrics (TEDS / GriTS) use to score OCR table output uniformly. Returns the recovered Table, or
Nonewhen the result carries no recoverable table structure.- Parameters:
ocr_result (
Any) – AnyOcrResult-shaped object. ek reads only its.raw(the engine-specific payload),.markdown(VLM/markdown engines), and.meta– never ocracy types, so anyimage -> OcrResultcallable’s output works.parser (
Union[None,str,Callable[[Any],Any]]) –How to turn the raw payload into a table (dependency injection / open-closed). One of:
None(default): try the built-in safe heuristics –.rawis already aTable, a 2-D grid, or a<table>...</table>HTML string; or.raw/.metais a mapping carrying one of{tables, table, cells, grid, html}; or.markdowncontains an HTML<table>. ReturnsNoneif none match – it never guesses wildly.a
str: the name of a parser registered under"table_parsers"(per-engine extractor), resolved fromek.registry.a callable
(raw) -> Table | grid | html | None: an inline per-engine extractor. It receives the result’s.raw(falling back to the result itself when there is no.raw).
through (Any non-None value an injected parser returns is fed)
- Return type:
Table | None
:param
Table.coerce(): :param so a parser may yield a Table: :param a 2-D grid: :param or HTML.:- Return type:
- Returns:
A non-empty
Table, orNonewhen no table structure is recoverable. An empty Table (no rows/cells) is normalized toNoneso the predicatehas_table_structure()and downstream metrics see “no table”, not a degenerate one.
Modules
End-to-end OCR offline benchmark: run a fleet over gold, score, persist. |
|
The |
|
Per-engine OCR capability profiles (what QE signal each engine actually emits). |
|
Recover a normalized table from an |