code wiki / (root) / nx_manga_ocr.nx

nx_manga_ocr.nx

buildroot/runtime/nx_manga_ocr.nx

4350 B93 linesdepth 11pulls 46 transitivereach 1 importersview sourcekind librarytopic manga
docsdependenciesstructsconstsfunctions

about

nx_manga_ocr.nx -- MG22: FIND THE TEXT REGIONS ON A PAGE (lib; lib+gate split, no main). The inverse of the lettering compositor: mb_bubble_draw DRAWS text into a box, this FINDS the box again. That makes the referee free -- our own emitter can produce any fixture this detector must recover -- which is why this rung needs no corpus and no model, unlike MG21 CJK recognition. COMPOSES THE INCUMBENT AND RE-IMPLEMENTS NOTHING: nx_reader_panels already ships the ink primitives this needs -- rp_ink_map (integer Otsu binarize, ink vs paper), rp_rowink and rp_colink (ink counts over a row or column segment). Panel detection and text detection are the SAME projection machinery at different scales: a panel is separated by a wide gutter, a text line by a narrow leading. Writing a second ink scanner beside that one would be the duplicate-ruler defect. METHOD, and its honest scope: horizontal projection groups inked rows into BANDS separated by more than MO_LINE_GAP rows of paper, then a vertical projection inside each band gives its extent. That finds INK CLUSTERS -- text lines and blocks. It does NOT yet distinguish a speech bubble from a caption or from dense hatching, and it does not read the bubble OUTLINE; that is the next rung and this header says so rather than letting a reader assume otherwise. POLICY-AS-CONSTS, DEBT DECLARED: the four thresholds below are named rather than buried, but named is not data -- they belong in a conf row beside knowledge/manga/layouts.conf, exactly as nx_manga_bubble's lettering style does. Filed as MG22-conf rather than left silent.

dependencies 2 imports · 1 importers

nx_syscalls.nx nx_reader_panels.nx nx_manga_ocr.nx nx_manga_ocr_gate.nx

imports: nx_syscalls.nxnx_reader_panels.nx

imported by: nx_manga_ocr_gate.nx

structs

none

consts

25const MO_MAXR: i64 = 64 // max regions returned; a FLOOR is announced by the caller, never silent
26const MO_MIN_INK: i64 = 2 // a row/col with fewer inked pixels than this counts as paper
27const MO_LINE_GAP: i64 = 3 // rows of paper that still belong to ONE text block (leading, not a break)
28const MO_MIN_W: i64 = 3 // a region narrower than this is speckle, not text
29const MO_MIN_H: i64 = 3 // a region shorter than this is speckle, not text
30const MO_FIELDS: i64 = 4 // x0 y0 x1 y1 per region

functions

33func mo_region_count(cap: i64) -> i64 { return cap / MO_FIELDS }
37func mo_text_regions(ink: *u8, W: i64, x0: i64, y0: i64, x1: i64, y1: i64, out: *i64) -> i64
called by 1: main calls 2: rp_rowinkrp_colink