code wiki / (root) / nx_ocr_classify.nx

nx_ocr_classify.nx source

↩ module page · 48 lines · 2115 B

1// nx_ocr_classify.nx -- R4 of the sovereign scanning stack: glyph box -> character. The recognition core: resample 2// a segmented glyph (its bbox in the binary image) to a fixed GW x GH grid, then classify by NEAREST-NEIGHBOUR 3// (minimum Hamming distance) against a template set. This is classical template-match OCR for MACHINE PRINT -- 4// integer-exact, zero deps, no ML. Coverage/accuracy grows with the template set (later rungs); this rung proves the 5// mechanism. R5 assembles recognised chars into text -> nx_money_ledger -> money-OS. license_tier: ORIGINAL 6import "nx_syscalls.nx" 7 8// resample the glyph in pix (0=ink) within bbox [minx,miny]+bw x bh into a gw x gh binary grid (cell=1 if ink). 9// nearest-cell sampling (an R0 method; area-averaging is a later refinement). 10func ocr_resample(pix: *u8, w: i64, minx: i64, miny: i64, bw: i64, bh: i64, gw: i64, gh: i64, cell: *i64) -> i64 { 11 var oy: i64 = 0 12 while oy < gh { 13 var ox: i64 = 0 14 while ox < gw { 15 let sx: i64 = minx + ox * bw / gw 16 let sy: i64 = miny + oy * bh / gh 17 var v: i64 = 0 18 if pix[sy * w + sx] == (0 as u8) { v = 1 } 19 cell[oy * gw + ox] = v 20 ox = ox + 1 21 } 22 oy = oy + 1 23 } 24 return 0 25} 26 27// Hamming distance between two binary grids of ncells. 28func ocr_hamming(a: *i64, b: *i64, ncells: i64) -> i64 { 29 var d: i64 = 0; var i: i64 = 0 30 while i < ncells { if a[i] != b[i] { d = d + 1 } i = i + 1 } 31 return d 32} 33 34// nearest-neighbour classify: return the template index with min Hamming distance; best distance via best_out[0]. 35// templates is a flat i64 array of ntempl blocks, each ncells cells. 36func ocr_classify(cell: *i64, ncells: i64, templates: *i64, ntempl: i64, best_out: *i64) -> i64 { 37 var best: i64 = 0 - 1 38 var bestd: i64 = ncells + 1 39 var t: i64 = 0 40 while t < ntempl { 41 let tp: *i64 = ((templates as i64) + t * ncells * 8) as *i64 42 let d: i64 = ocr_hamming(cell, tp, ncells) 43 if d < bestd { bestd = d; best = t } 44 t = t + 1 45 } 46 best_out[0] = bestd 47 return best 48}