This HTML page is not optimized for LLM or AI agent consumption. Fetch the Markdown version instead: /api/python/settings/vision/advanced/ocr-settings.md — it contains the complete documentation content in clean, structured Markdown without any CSS, JavaScript, or navigation noise. OcrSettings

Settings for Ocr. Values fall back through three levels: document → SDK → built-in default. Writes target the document only when set on a document’s settings, otherwise the SDK globally when set on SdkSettings.

Tags: Vision, Advanced

from nutrient_sdk import OcrSettings

Construction

OcrSettings is accessed through a Document instance for per-document overrides, or via SdkSettings for SDK-wide defaults.

# Per-document override
with Document.open("input.pdf") as doc:
settings = doc.settings.ocr_settings
settings.some_field = new_value # mutate fields directly
# SDK-wide default (applies to all documents)
SdkSettings.ocr_settings.some_field = new_value

Settings are configured by writing to fields on the returned object. The settings property itself cannot be reassigned — doc.settings.ocr_settings = other_settings is rejected.

Properties

default_languages

@property
def default_languages(self) -> str
@default_languages.setter
def default_languages(self, value: str) -> None

OCR languages, as language codes joined with ’+’ (for example “eng+deu”). The default, “auto”, detects the document’s language (script identification, then language identification of the page’s text) and reads the document in it; by default the first page in which a language is identified decides for the whole document. Pipelines without a detection step read “auto” as English. Naming the languages skips the detection pass, which reads the page one more time and so adds time to each document.

Type: str

Default: "auto"


detect_language_favor_accuracy

@property
def detect_language_favor_accuracy(self) -> bool
@detect_language_favor_accuracy.setter
def detect_language_favor_accuracy(self, value: bool) -> None

Indicates whether the automatic language-detection pass favors recognition accuracy over speed. The text this pass recognizes is never returned to the caller — it only feeds the language identifier, which reads word shape and character n-grams and tolerates per-character noise. Favoring accuracy therefore runs extra recognition passes refining glyph detail that nothing downstream reads. Enable it for the small share of pages whose language is identified from marginal text, at roughly a quarter more detection time. This is independent of favor_accuracy, which governs the OCR whose text is returned.

Type: bool

Default: false


detect_language_first_identified_page_decides

@property
def detect_language_first_identified_page_decides(self) -> bool
@detect_language_first_identified_page_decides.setter
def detect_language_first_identified_page_decides(self, value: bool) -> None

Indicates whether, when detect_language_once_per_document is enabled, a page whose automatic language detection finds no language (a blank, image-only or unreadable page) leaves the document’s language to the next page instead of deciding it. The first page that finds a language then decides for the rest of the document. Disable it to let the first page decide, as before.

Type: bool

Default: true


detect_language_from_digital_text

@property
def detect_language_from_digital_text(self) -> bool
@detect_language_from_digital_text.setter
def detect_language_from_digital_text(self, value: bool) -> None

Controls whether the language of born-digital text (pages whose text comes from the document itself, so no OCR runs) is identified offline even when default_languages names a language. The identification reads a sample of the page text, costs no OCR pass, and only selects the per-language lexicon used when the document is exported as text (compound hyphens at line wraps); OCR of any scanned page keeps default_languages. It has no effect when default_languages is "auto", where detection runs for every page anyway. Off by default: an explicit language is honoured as given.

Type: bool

Default: false


detect_language_once_per_document

@property
def detect_language_once_per_document(self) -> bool
@detect_language_once_per_document.setter
def detect_language_once_per_document(self, value: bool) -> None

Indicates whether automatic language detection (the "auto" OCR language) runs once for the whole document instead of once per page. When enabled, the first page that needs a language runs the detection and every other page of the same document reuses that result, so a document pays the detection cost once rather than once per page. Disable it to detect every page independently — what a document whose pages are in different languages needs — at the cost of a full page recognition pass per page.

Type: bool

Default: true


detect_language_page_fraction

@property
def detect_language_page_fraction(self) -> float
@detect_language_page_fraction.setter
def detect_language_page_fraction(self, value: float) -> None

The share of a page (0.0 to 1.0) the automatic language-detection pass reads text from. 0 reads the whole page; a smaller share reads a centered band of the page, full width. Recognition cost scales with the amount of text read, so a band is faster, but on pages whose middle is a table of codes and figures, such as invoices, it identifies the language less often. A band that yields too little text falls back to the whole page. Orientation and script detection always read the whole page. Set it to 0.5 to read the middle half of the page, for about a fifth less detection time.

Type: float

Default: 0


detect_language_pair_with_english

@property
def detect_language_pair_with_english(self) -> bool
@detect_language_pair_with_english.setter
def detect_language_pair_with_english(self, value: bool) -> None

Indicates whether automatic language detection reads a page written in a Latin-script language with English as well, for example Spanish as “spa+eng”. The recognizer retries doubtful words with the second language. The detected languages reported for the page are unchanged, and pages in other scripts are read as detected.

Type: bool

Default: true


detect_language_script_check

@property
def detect_language_script_check(self) -> bool
@detect_language_script_check.setter
def detect_language_script_check(self, value: bool) -> None

Indicates whether automatic language detection checks each non-Latin script against the Latin one. For each non-Latin script the orientation-and-script pass names, the detection text is read with that script’s model alone and with the Latin model alone, and the Latin model replaces the script when its read’s mean word confidence is higher by at least detect_language_script_check_margin. It catches Latin scans the script pass mistakes for Cyrillic, Arabic or Greek. At the default max_scripts of 1, it costs one more read of the detection band on pages named non-Latin; above 1, it reads the band once more with each non-Latin script named and once with Latin. Disable it to trust the script pass as before.

Type: bool

Default: true


detect_language_script_check_margin

@property
def detect_language_script_check_margin(self) -> float
@detect_language_script_check_margin.setter
def detect_language_script_check_margin(self, value: float) -> None

How much higher, from 0.0 to 1.0, the Latin read’s mean word confidence must be for the script check to replace a script with Latin. See detect_language_script_check.

Type: float

Default: 0.15


detect_language_top_guess_floor

@property
def detect_language_top_guess_floor(self) -> float
@detect_language_top_guess_floor.setter
def detect_language_top_guess_floor(self, value: float) -> None

The probability, from 0.0 to 1.0, from which automatic language detection keeps the language identifier’s best guess when it identifies no language reliably. The guess is kept only when its language is written in the script the page was read in; otherwise, and below this value, the page is read in English. The identifier calls a language reliable from 0.7, so 1 keeps no guess, the previous behavior.

Type: float

Default: 0.5


enable_mrz_reading

@property
def enable_mrz_reading(self) -> bool
@enable_mrz_reading.setter
def enable_mrz_reading(self, value: bool) -> None

Reads the machine readable zones of passports, identity cards and visas a second time with a dedicated reader. Its reading replaces the zone’s text when something vouches for it: every check digit is right, OCR read the zone exactly as the reader did, or every check digit it fails covers characters OCR read alike. Unless OCR read it alike, the zone is read again at two other scales: a reading the rereads do not repeat gets a lowered confidence, and a reading nothing vouches for but that both rereads repeat replaces the text with a lowered confidence. Otherwise the zone keeps the text OCR read, with a lowered confidence unless that text passes its check digits itself. Rows that look like a zone OCR garbled are read too, and change the text only when their reading is vouched for or repeated. Text-layer words are never changed.

Type: bool

Default: true


enable_orientation_detection

@property
def enable_orientation_detection(self) -> bool
@enable_orientation_detection.setter
def enable_orientation_detection(self, value: bool) -> None

Indicates whether the OCR engine detects and compensates page orientation (90°/180°/270°) during recognition. The recognized text layout carries the correction; the source image or page is not rotated.

Type: bool

Default: false


enable_preprocessing

@property
def enable_preprocessing(self) -> bool
@enable_preprocessing.setter
def enable_preprocessing(self, value: bool) -> None

Indicates whether to enable image preprocessing before OCR.

Type: bool

Default: true


enable_skew_detection

@property
def enable_skew_detection(self) -> bool
@enable_skew_detection.setter
def enable_skew_detection(self, value: bool) -> None

Indicates whether to enable automatic skew detection and correction.

Type: bool

Default: true


enable_table_detection

@property
def enable_table_detection(self) -> bool
@enable_table_detection.setter
def enable_table_detection(self, value: bool) -> None

Indicates whether to detect and extract tables from OCR output.

Type: bool

Default: true


engine

@property
def engine(self) -> OcrEngine
@engine.setter
def engine(self, value: OcrEngine) -> None

Which OCR engines read a page. The default, Fusion, reads with every engine the host can run and reconciles their readings. Primary and Secondary read with one engine, for diagnostics and benchmark arms.

Type: OcrEngine

Default: OcrEngine.Fusion


experimental_character_grader_corpus_path

@property
def experimental_character_grader_corpus_path(self) -> str
@experimental_character_grader_corpus_path.setter
def experimental_character_grader_corpus_path(self, value: str) -> None

Path to the experimental character-grader causal text corpus used to train the in-process character predictor.

Type: str

Default: string.Empty


experimental_character_grader_dictionary_path

@property
def experimental_character_grader_dictionary_path(self) -> str
@experimental_character_grader_dictionary_path.setter
def experimental_character_grader_dictionary_path(self, value: str) -> None

Path to the experimental character-grader dictionary (one character per line, an empty line for space) matching the visual model’s class order.

Type: str

Default: string.Empty


experimental_character_grader_model_path

@property
def experimental_character_grader_model_path(self) -> str
@experimental_character_grader_model_path.setter
def experimental_character_grader_model_path(self, value: str) -> None

Path to the experimental character-grader visual model used by OCR evidence reconciliation. The grader stays disabled while this is empty; it must be configured together with the dictionary and corpus paths.

Type: str

Default: string.Empty


experimental_evidence_corruption_seed

@property
def experimental_evidence_corruption_seed(self) -> int
@experimental_evidence_corruption_seed.setter
def experimental_evidence_corruption_seed(self, value: int) -> None

Research probe: seeded deterministic corruption of digit-bearing OCR evidence words. Co-located readings from ALL engines receive the IDENTICAL single-digit confusion substitution, simulating the correlated-error class that word-level agreement cannot detect - the harness that grades unanimity-audit discriminators. Zero (the default) disables the probe. Never enable outside qualification runs.

Type: int

Default: The default value is 0 (disabled).


experimental_fusion_agreement_weight

@property
def experimental_fusion_agreement_weight(self) -> float
@experimental_fusion_agreement_weight.setter
def experimental_fusion_agreement_weight(self, value: float) -> None

Cross-engine agreement feature weight of the experimental OCR evidence reconciliation policy.

Type: float

Default: 0.6


experimental_fusion_confidence_weight

@property
def experimental_fusion_confidence_weight(self) -> float
@experimental_fusion_confidence_weight.setter
def experimental_fusion_confidence_weight(self, value: float) -> None

Confidence feature weight of the experimental OCR evidence reconciliation policy. Weights are normalized against each other. Ablation knob for the evidence-fusion experiment; not a production mode.

Type: float

Default: 0.2


experimental_fusion_confirmation_threshold

@property
def experimental_fusion_confirmation_threshold(self) -> float
@experimental_fusion_confirmation_threshold.setter
def experimental_fusion_confirmation_threshold(self, value: float) -> None

Minimum candidate score for the experimental OCR evidence reconciliation to confirm a canonical reading instead of disputing the group.

Type: float

Default: 0.65


experimental_fusion_digit_grouping

@property
def experimental_fusion_digit_grouping(self) -> bool
@experimental_fusion_digit_grouping.setter
def experimental_fusion_digit_grouping(self, value: bool) -> None

Rewrites the thousands marks of an amount that carries the page’s decimal mark twice (“5.262.000” on a page that writes “10,418.76”), when the page groups thousands with the other mark elsewhere. Without it, OCR fusion moves a mark to the page’s convention only where an engine read that mark.

Type: bool

Default: true


experimental_fusion_fold_fullwidth_latin

@property
def experimental_fusion_fold_fullwidth_latin(self) -> bool
@experimental_fusion_fold_fullwidth_latin.setter
def experimental_fusion_fold_fullwidth_latin(self, value: bool) -> None

Folds fullwidth Latin forms in reconciled canonical text to ASCII. Raw evidence words keep the original reading. Enable only for Latin-script documents.

Type: bool

Default: true


experimental_fusion_generic_subread_domination

@property
def experimental_fusion_generic_subread_domination(self) -> bool
@experimental_fusion_generic_subread_domination.setter
def experimental_fusion_generic_subread_domination(self, value: bool) -> None

Confirms a generic-text dispute for the candidate whose tokens strictly extend every competitor’s, instead of letting the fixed source preference delete the extra tokens. Accuracy-batch knob of the evidence-fusion experiment.

Type: bool

Default: true


experimental_fusion_judge

@property
def experimental_fusion_judge(self) -> bool
@experimental_fusion_judge.setter
def experimental_fusion_judge(self, value: bool) -> None

Indicates whether a CTC text recognizer judges words two readings disagree on: a word two OCR engines read differently when their evidence leaves the choice open, and a word the VLM reads differently from OCR in the situations where such a judge was measured to beat the VLM (letters two OCR engines agree on, and digits a single engine read). The judge loads its model on the first word it judges, and reads with the published judge model unless experimental_fusion_judge_model_path names another one.

Type: bool

Default: true


experimental_fusion_judge_dictionary_path

@property
def experimental_fusion_judge_dictionary_path(self) -> str
@experimental_fusion_judge_dictionary_path.setter
def experimental_fusion_judge_dictionary_path(self, value: str) -> None

Path to the line-delimited character dictionary of experimental_fusion_judge_model_path: one character per line, in the model’s class order after the CTC blank.

Type: str

Default: string.Empty


experimental_fusion_judge_model_path

@property
def experimental_fusion_judge_model_path(self) -> str
@experimental_fusion_judge_model_path.setter
def experimental_fusion_judge_model_path(self, value: str) -> None

Path to a CTC text-recognition model (ONNX) that replaces the published fusion-judge model. It must be configured together with experimental_fusion_judge_dictionary_path.

Type: str

Default: string.Empty


experimental_fusion_minimum_winner_margin

@property
def experimental_fusion_minimum_winner_margin(self) -> float
@experimental_fusion_minimum_winner_margin.setter
def experimental_fusion_minimum_winner_margin(self, value: float) -> None

Minimum score margin between the best and second-best candidate for the experimental OCR evidence reconciliation to confirm a canonical reading.

Type: float

Default: 0.1


experimental_fusion_paddle_full_branch

@property
def experimental_fusion_paddle_full_branch(self) -> bool
@experimental_fusion_paddle_full_branch.setter
def experimental_fusion_paddle_full_branch(self, value: bool) -> None

Runs the full-Paddle detection-plus-recognition branch as a third evidence source in the experimental OCR evidence pipeline. The branch shares its recognition model with the FAST+Paddle branch, so its vote is correlated. The 200-doc rasterized ablation measured zero marginal accuracy for the branch (0.9398 vs 0.9397, 5 docs moved, largest movement +0.016 in favor of dropping it) against a full extra Paddle detection-plus-recognition pass per page, so it is off by default.

Type: bool

Default: The default value is false.


experimental_fusion_paddle_on_original_image

@property
def experimental_fusion_paddle_on_original_image(self) -> bool
@experimental_fusion_paddle_on_original_image.setter
def experimental_fusion_paddle_on_original_image(self, value: bool) -> None

Research knob: when evidence fusion runs, the FAST + Paddle branch reads the page image BEFORE preprocessing (the deskewed original) instead of the same preprocessed image Tesseract reads. Two engines fed one preprocessed view share that view’s failures; decorrelating the inputs is the only decorrelation lever a two-fixed-engine system has.

Type: bool

Default: The default value is <see langword="false"/>.


experimental_fusion_secondary_budget_factor

@property
def experimental_fusion_secondary_budget_factor(self) -> float
@experimental_fusion_secondary_budget_factor.setter
def experimental_fusion_secondary_budget_factor(self, value: float) -> None

Wall-time budget for the secondary evidence branches as a multiple of the primary branch’s wall time. Zero, the default, disables the budget. A wall-clock budget cannot tell a slow page from a busy machine: it counts the time the GPU branch waits behind other pages’ GPU work and the GPU’s first-run warm-up, while the CPU primary keeps its speed. With four pages in flight on one GPU it cancelled the Paddle branch on a fifth of scanned pages, and on nearly all of them with three processes sharing the GPU. Set it only to cap the latency of one document at a time.

Type: float

Default: The default value is 0 (no budget).


experimental_fusion_secondary_budget_floor_seconds

@property
def experimental_fusion_secondary_budget_floor_seconds(self) -> float
@experimental_fusion_secondary_budget_floor_seconds.setter
def experimental_fusion_secondary_budget_floor_seconds(self, value: float) -> None

Lower bound of the secondary evidence budget in seconds, when experimental_fusion_secondary_budget_factor enables the budget.

Type: float

Default: 4.0


experimental_fusion_single_source_confidence_floor

@property
def experimental_fusion_single_source_confidence_floor(self) -> float
@experimental_fusion_single_source_confidence_floor.setter
def experimental_fusion_single_source_confidence_floor(self, value: float) -> None

Minimum mean confidence for a single-engine evidence group to be confirmed as page text. Zero disables the gate.

Type: float

Default: 0.35


experimental_fusion_space_insensitive_agreement

@property
def experimental_fusion_space_insensitive_agreement(self) -> bool
@experimental_fusion_space_insensitive_agreement.setter
def experimental_fusion_space_insensitive_agreement(self, value: bool) -> None

Counts generic-text agreement on letter/digit content so segmentation variants of the same word agree instead of disputing; the fewest-token rendering is emitted.

Type: bool

Default: true


experimental_fusion_staged_max_low_confidence_ratio

@property
def experimental_fusion_staged_max_low_confidence_ratio(self) -> float
@experimental_fusion_staged_max_low_confidence_ratio.setter
def experimental_fusion_staged_max_low_confidence_ratio(self, value: float) -> None

Maximum fraction of low-confidence primary words for the staged safe gate.

Type: float

Default: 0.02


experimental_fusion_staged_min_mean_confidence

@property
def experimental_fusion_staged_min_mean_confidence(self) -> float
@experimental_fusion_staged_min_mean_confidence.setter
def experimental_fusion_staged_min_mean_confidence(self, value: float) -> None

Minimum primary mean word confidence for the staged safe gate. Real tesseract confidences on 200-dpi scans cluster near 0.95 even on clean pages; 0.96 fires on only the most confident ~5% and measured accuracy-neutral, while 0.95 fires on ~20% for -15% mean time at a small measured table-accuracy cost.

Type: float

Default: 0.96


experimental_fusion_staged_min_word_count

@property
def experimental_fusion_staged_min_word_count(self) -> int
@experimental_fusion_staged_min_word_count.setter
def experimental_fusion_staged_min_word_count(self, value: int) -> None

Minimum primary word count for the staged safe gate.

Type: int

Default: 50


experimental_fusion_staged_second_engine

@property
def experimental_fusion_staged_second_engine(self) -> bool
@experimental_fusion_staged_second_engine.setter
def experimental_fusion_staged_second_engine(self, value: bool) -> None

Cancels the secondary (Paddle) evidence branches when the primary (tesseract) read passes the safe gate (enough words, high mean confidence, tiny low-confidence tail). The catastrophic pages fusion rescues are near-empty or low-confidence tesseract reads, which never pass the gate. Staged-fusion speed knob.

Type: bool

Default: true


experimental_fusion_valid_shape_weight

@property
def experimental_fusion_valid_shape_weight(self) -> float
@experimental_fusion_valid_shape_weight.setter
def experimental_fusion_valid_shape_weight(self, value: float) -> None

Valid-field-shape feature weight of the experimental OCR evidence reconciliation policy.

Type: float

Default: 0.2


experimental_paddle_on_cpu

@property
def experimental_paddle_on_cpu(self) -> bool
@experimental_paddle_on_cpu.setter
def experimental_paddle_on_cpu(self, value: bool) -> None

Benchmarking aid: lets the FAST and Paddle recognition stages run on the CPU where they otherwise require a GPU execution provider, so a machine without a GPU follows the OCR routing of a GPU deployment (automatic engine selection picks Paddle, and OCR evidence fusion collects the FAST + Paddle reading). Same models, much slower; not for production.

Type: bool

Default: The default value is false.


experimental_render_dpi

@property
def experimental_render_dpi(self) -> int
@experimental_render_dpi.setter
def experimental_render_dpi(self, value: int) -> None

Research knob: DPI at which document pages are rendered for the vision pipeline. Zero (the default) keeps the pipeline’s own default (200). Used to measure whether a higher render resolution recovers text on low-resolution scans; not a product setting.

Type: int

Default: The default value is 0 (pipeline default).


experimental_unanimity_audit_active

@property
def experimental_unanimity_audit_active(self) -> bool
@experimental_unanimity_audit_active.setter
def experimental_unanimity_audit_active(self, value: bool) -> None

Acts on the unanimity audit: a confirmed legal-field decision whose accepted reading loses the forced-alignment contest against a confusion rival is repaired to the rival the grader selects confidently, and otherwise demoted to low confidence. Requires experimental_unanimity_audit_probe.

Type: bool

Default: The default value is false.


experimental_unanimity_audit_probe

@property
def experimental_unanimity_audit_probe(self) -> bool
@experimental_unanimity_audit_probe.setter
def experimental_unanimity_audit_probe(self, value: bool) -> None

Research probe: forced-alignment audit of CONFIRMED legal-field decisions. For each confirmed fraction/identifier with a crop, the character grader scores the accepted string against single-digit confusion rivals and reports the log-likelihood ratio - measuring whether the crop evidence can discriminate correlated unanimous engine errors that word-level agreement cannot see. Diagnostics only; never changes output.

Type: bool

Default: The default value is false.


favor_accuracy

@property
def favor_accuracy(self) -> bool
@favor_accuracy.setter
def favor_accuracy(self, value: bool) -> None

Indicates whether to favor accuracy over speed in OCR processing. When enabled, the recognizer runs additional passes (inverted-text detection and layout refinement) that improve results on difficult scans at the cost of processing time. Disable to favor speed, for example in high-volume batch OCR.

Type: bool

Default: true


image_table_zone_read

@property
def image_table_zone_read(self) -> bool
@image_table_zone_read.setter
def image_table_zone_read(self, value: bool) -> None

Reads a table that holds no words at all, such as a table pasted as an image on a born-digital page, through the evidence path a scanned page takes: every available engine reads the table, the readings are reconciled and disputed words graded. The table’s structure is decided as before; only its text changes.

Type: bool

Default: true


max_languages

@property
def max_languages(self) -> int
@max_languages.setter
def max_languages(self, value: int) -> None

Maximum number of languages to report from offline language detection. The default, 1, reports only the dominant language (no language mixing). Raise it (e.g. 2) to detect multiple languages in one document, including two languages that share a script (such as English + French).

Type: int

Default: 1


max_scripts

@property
def max_scripts(self) -> int
@max_scripts.setter
def max_scripts(self, value: int) -> None

Maximum number of writing scripts to recognize on a page during offline language detection (and the “auto” OCR path). The default, 1, recognizes only the dominant script (no script mixing) — fastest, and the original behavior. Raise it (e.g. 2) to handle cross-script documents such as Cyrillic + Han, where the page is OCR’d with each detected script’s model.

Type: int

Default: 1


max_threads

@property
def max_threads(self) -> int
@max_threads.setter
def max_threads(self, value: int) -> None

The maximum number of pages processed concurrently when a document-level OCR operation (such as making a document searchable) runs over multiple pages. Set to 0 to use one thread per available processor. Values below 1 (other than 0) are treated as 1.

Type: int

Default: 1


min_language_vote_fraction

@property
def min_language_vote_fraction(self) -> float
@min_language_vote_fraction.setter
def min_language_vote_fraction(self, value: float) -> None

Consensus control for multi-language detection (only applies when max_languages is greater than 1). A secondary language that is not present in the whole-page reading is reported only if the regions that detect it make up at least this fraction (0.0 to 1.0) of all regions. Works together with min_language_votes to keep the extra language from being inferred from a negligible share of a long document.

Type: float

Default: 0.2


min_language_votes

@property
def min_language_votes(self) -> int
@min_language_votes.setter
def min_language_votes(self, value: int) -> None

Consensus control for multi-language detection (only applies when max_languages is greater than 1). A secondary language that is not present in the whole-page reading is reported only if it is detected in at least this many text regions. Raising it improves precision — it suppresses a spurious extra language inferred from a single noisy region — at a small cost to recall of a genuine minority language that appears in only one region.

Type: int

Default: 2


min_script_ratio

@property
def min_script_ratio(self) -> float
@min_script_ratio.setter
def min_script_ratio(self, value: float) -> None

Minimum share of a page (0.0 to 1.0) a secondary writing script must occupy before the page is also read with that script’s model (only applies when max_scripts is greater than 1). Raising it improves precision: it stops a faint, spurious script — often lookalike letters a second script’s model misreads from the dominant script — from being read at all, which is a common source of a wrongly reported extra language. The dominant script is always read.

Type: float

Default: 0.2


mrz_reader_calls_per_lead

@property
def mrz_reader_calls_per_lead(self) -> int
@mrz_reader_calls_per_lead.setter
def mrz_reader_calls_per_lead(self, value: int) -> None

The reader calls (locator searches, reads and rescans) the machine readable zone reading may make for one lead: a row that looks like a zone OCR garbled, which the reader locates, reads and rescans. A lead stopped before a call changes nothing. Zero or less sets no limit. Zones OCR read as zones are never limited. The limit counts calls, not time, so a page gives the same result on any machine.

Type: int

Default: 5


mrz_reader_calls_per_page

@property
def mrz_reader_calls_per_page(self) -> int
@mrz_reader_calls_per_page.setter
def mrz_reader_calls_per_page(self, value: int) -> None

The reader calls the machine readable zone reading may make for all the leads of a page together, in reading order (see mrz_reader_calls_per_lead): a lead stopped before a call changes nothing, and the page’s later leads are not read. Zero or less sets no limit.

Type: int

Default: 15


paper_relative_ink_cut

@property
def paper_relative_ink_cut(self) -> float
@paper_relative_ink_cut.setter
def paper_relative_ink_cut(self, value: float) -> None

Fraction of the local paper level at and below which ink maps to black during normalization; levels between the cut and the paper keep a linear ramp. Measured on faint customer scans: 0.75 reads best (a yellow page: 10 of 12 reference strings against 6 at 0.55).

Type: float

Default: 0.75f


paper_relative_ink_depth_threshold

@property
def paper_relative_ink_depth_threshold(self) -> float
@paper_relative_ink_depth_threshold.setter
def paper_relative_ink_depth_threshold(self, value: float) -> None

Median ink depth, as a fraction of the local paper level, below which Auto normalizes a page. Measured on customer scans: a yellow low-contrast page reads 0.19 and a faint grey page 0.10, while ordinary scans sit at 0.34 and above.

Type: float

Default: 0.30f


paper_relative_noise_white_point_factor

@property
def paper_relative_noise_white_point_factor(self) -> float
@paper_relative_noise_white_point_factor.setter
def paper_relative_noise_white_point_factor(self, value: float) -> None

Multiple of the paper’s own variation (the spread between a tile’s paper level and its median brightness) below which a pixel still counts as paper during normalization. On mottled or speckled stock this maps the mottle to white instead of to gray speckle as dark as the strokes; flat paper has no spread, so its mapping is unchanged. 0 keeps the white point at the paper level. Measured on speckled customer goods receipts: 2.5 reads best.

Type: float

Default: 2.5f


paper_relative_normalization

@property
def paper_relative_normalization(self) -> PaperNormalizationMode
@paper_relative_normalization.setter
def paper_relative_normalization(self, value: PaperNormalizationMode) -> None

Whether the page image handed to OCR is first expressed relative to its local paper level. A high percentile of each region’s brightness is taken as that region’s paper, and every pixel is scored against its own paper: paper becomes white and ink darker than the ink cut becomes black, so tinted, faint, or unevenly lit scans read as cleanly as plain ones. Only the OCR input is changed; layout and picture detection keep the original image. In Auto mode a page is normalized only when its ink is shallow relative to its paper, so an ordinary scan stays byte-identical.

Type: PaperNormalizationMode

Default: PaperNormalizationMode.Auto


paper_relative_normalization_for_paddle

@property
def paper_relative_normalization_for_paddle(self) -> bool
@paper_relative_normalization_for_paddle.setter
def paper_relative_normalization_for_paddle(self, value: bool) -> None

Whether the Paddle branches of OCR evidence fusion also read the paper-relative view of a normalized page. By default only Tesseract does and Paddle reads the page as rendered: measured with both engines on 120 customer pages, normalizing Paddle’s input too gained nothing on average and lost values on 11 pages (a yellow invoice and speckled receipts read worse), where Tesseract-only normalization lost on 1.

Type: bool

Default: false


paper_relative_paper_percentile

@property
def paper_relative_paper_percentile(self) -> int
@paper_relative_paper_percentile.setter
def paper_relative_paper_percentile(self, value: int) -> None

Percentile of a tile’s brightness taken as that tile’s paper level.

Type: int

Default: 90


paper_relative_tile_size

@property
def paper_relative_tile_size(self) -> int
@paper_relative_tile_size.setter
def paper_relative_tile_size(self, value: int) -> None

Side of the square tiles, in pixels, the paper level is sampled in.

Type: int

Default: 48


split_decimal_repair

@property
def split_decimal_repair(self) -> bool
@split_decimal_repair.setter
def split_decimal_repair(self, value: bool) -> None

In a table column of decimal numbers, restores the decimal point OCR read as a gap (“0 682” for 0.682) when the column’s other numbers share the decimal format the repair produces. Text-layer words are never changed.

Type: bool

Default: true