code wiki / (root) / nx_img_segment_gate.nx

nx_img_segment_gate.nx source

↩ module page · 59 lines · 3010 B

1// nx_img_segment_gate.nx -- proves R3 (connected-component segmentation) on a 5x5 binary image with TWO separate 2// ink blobs: a 2x2 block top-left and a vertical pair on the right edge. Verifies component count, per-component 3// bounding boxes, and a couple of label assignments. Exit 0 iff all pass. license_tier: ORIGINAL 4import "nx_gate.nx" 5import "nx_img_segment.nx" 6 7func chk(name: *u8, got: i64, want: i64, st: *i64) -> i64 { 8 if got == want { st[0] = st[0] + 1; gw(" PASS " as *u8); gw(name); gw("\n" as *u8) } 9 else { st[1] = st[1] + 1; gw(" FAIL " as *u8); gw(name); gw(" got=" as *u8); gn(got); gw(" want=" as *u8); gn(want); gw("\n" as *u8) } 10 return 0 11} 12 13func main() -> i64 { 14 let st: *i64 = sys_mmap(16) as *i64 15 st[0] = 0; st[1] = 0 16 17 // row0: . . . . . (. = paper 255, # = ink 0) 18 // row1: # # . . . 19 // row2: # # . . # 20 // row3: . . . . # 21 // row4: . . . . . 22 let src: *u8 = "P2\n5 5\n255\n255 255 255 255 255\n0 0 255 255 255\n0 0 255 255 0\n255 255 255 255 0\n255 255 255 255 255\n" as *u8 23 var len: i64 = 0; while src[len] != (0 as u8) { len = len + 1 } 24 let pix: *u8 = sys_mmap(1024) 25 let dims: *i64 = sys_mmap(64) as *i64 26 let n: i64 = img_pgm_decode(src, len, pix, 1024, dims) 27 chk("decoded 25 pixels" as *u8, n, 25, st) 28 29 let labels: *i64 = sys_mmap(1024 * 8) as *i64 30 let boxes: *i64 = sys_mmap(64 * 8) as *i64 31 let ncomp: i64 = seg_components(pix, 5, 5, labels, boxes, 64) 32 chk("2 connected components" as *u8, ncomp, 2, st) 33 34 // component 1 = the 2x2 block top-left: bbox (0,1)-(1,2) 35 chk("comp1 minx = 0" as *u8, seg_box_minx(boxes, 1), 0, st) 36 chk("comp1 miny = 1" as *u8, seg_box_miny(boxes, 1), 1, st) 37 chk("comp1 maxx = 1" as *u8, seg_box_maxx(boxes, 1), 1, st) 38 chk("comp1 maxy = 2" as *u8, seg_box_maxy(boxes, 1), 2, st) 39 chk("comp1 width = 2" as *u8, seg_box_width(boxes, 1), 2, st) 40 chk("comp1 height = 2" as *u8, seg_box_height(boxes, 1), 2, st) 41 42 // component 2 = the vertical pair on the right edge: bbox (4,2)-(4,3) 43 chk("comp2 minx = 4" as *u8, seg_box_minx(boxes, 2), 4, st) 44 chk("comp2 miny = 2" as *u8, seg_box_miny(boxes, 2), 2, st) 45 chk("comp2 maxx = 4" as *u8, seg_box_maxx(boxes, 2), 4, st) 46 chk("comp2 maxy = 3" as *u8, seg_box_maxy(boxes, 2), 3, st) 47 chk("comp2 width = 1" as *u8, seg_box_width(boxes, 2), 1, st) 48 chk("comp2 height = 2" as *u8, seg_box_height(boxes, 2), 2, st) 49 50 // label spot-checks (raster order: blob1 found first -> id 1; blob2 -> id 2) 51 chk("label at (0,1) = comp 1" as *u8, labels[1 * 5 + 0], 1, st) 52 chk("label at (4,2) = comp 2" as *u8, labels[2 * 5 + 4], 2, st) 53 chk("label at (0,0) = background 0" as *u8, labels[0], 0, st) 54 55 gw("nx_img_segment_gate: PASS=" as *u8); gn(st[0]); gw(" FAIL=" as *u8); gn(st[1]); gw("\n" as *u8) 56 if st[1] == 0 { gw("R3 nx_img_segment: GREEN (8-connected components + glyph bounding boxes)\n" as *u8); return 0 } 57 gw("R3 nx_img_segment: RED\n" as *u8) 58 return 1 59}