nx_manga_ocr.nx
buildroot/runtime/nx_manga_ocr.nx
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
imports: nx_syscalls.nxnx_reader_panels.nx
imported by: nx_manga_ocr_gate.nx
structs
| none |
consts
| 25 | const MO_MAXR: i64 = 64 // max regions returned; a FLOOR is announced by the caller, never silent |
| 26 | const MO_MIN_INK: i64 = 2 // a row/col with fewer inked pixels than this counts as paper |
| 27 | const MO_LINE_GAP: i64 = 3 // rows of paper that still belong to ONE text block (leading, not a break) |
| 28 | const MO_MIN_W: i64 = 3 // a region narrower than this is speckle, not text |
| 29 | const MO_MIN_H: i64 = 3 // a region shorter than this is speckle, not text |
| 30 | const MO_FIELDS: i64 = 4 // x0 y0 x1 y1 per region |
functions
| 33 | func mo_region_count(cap: i64) -> i64 { return cap / MO_FIELDS } |
| 37 | func mo_text_regions(ink: *u8, W: i64, x0: i64, y0: i64, x1: i64, y1: i64, out: *i64) -> i64 |