nx_skin_diag.nx source
↩ module page · 162 lines · 7226 B
1// nx_skin_diag.nx -- VISIBLE diagnostic: is the skin detector accurate on the
2// real gallery, or do the images not look real, or both? For each PNG in
3// idx_in.txt it decodes, classifies every pixel, and writes a skin-MASK BMP
4// (skin -> magenta, non-skin -> dimmed gray) you can open on Windows to SEE
5// exactly what the detector calls skin. Also prints skin permille and a
6// presence-by-FRACTION verdict (skin >= 200 permille), so you can compare the
7// fraction rule against the (mis-designed) concentration gate.
8//
9// Output: knowledge/staging/media/mask_<i>.bmp
10// Sovereign: syscalls + nx_media_index (decode+presence deps) + nx_bmp.
11// license_tier: ORIGINAL
12import "nx_syscalls.nx"
13import "nx_media_index.nx"
14import "nx_bmp.nx"
15import "nx_blob.nx"
16const PRESENT_MAGIC_4096: i64 = 4096
17const PRESENT_MAGIC_4095: i64 = 4095
18
19const PRESENT_FRAC: i64 = 200 // skin permille floor for the fraction rule
20
21func gp(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
22func gn(v: i64) -> i64 {
23 let bb: *u8 = sys_mmap(28)
24 var m: i64 = v
25 if m < 0 { sys_write(1, "-\x00" as *u8, 1); m = 0 - m }
26 let t: *u8 = sys_mmap(28)
27 var k: i64 = 0
28 if m == 0 { t[0] = 48 as u8; k = 1 }
29 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
30 var i: i64 = 0
31 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 }
32 sys_write(1, bb, k)
33 return 0
34}
35func itoa_into(buf: *u8, off: i64, v: i64) -> i64 {
36 if v == 0 { buf[off] = 48 as u8; return off + 1 }
37 let tmp: *u8 = sys_mmap(28)
38 var m: i64 = v
39 var kk: i64 = 0
40 while m > 0 { tmp[kk] = (48 + (m % 10)) as u8; m = m / 10; kk = kk + 1 }
41 var i: i64 = 0
42 while i < kk { buf[off + i] = tmp[kk - 1 - i]; i = i + 1 }
43 return off + kk
44}
45func build_mask_path(buf: *u8, idx: i64) -> i64 {
46 let pre: *u8 = "knowledge/staging/media/mask_\x00" as *u8
47 var p: i64 = 0
48 while pre[p] != (0 as u8) { buf[p] = pre[p]; p = p + 1 }
49 var off: i64 = itoa_into(buf, p, idx)
50 let suf: *u8 = ".bmp\x00" as *u8
51 var s: i64 = 0
52 while suf[s] != (0 as u8) { buf[off + s] = suf[s]; s = s + 1 }
53 buf[off + s] = 0 as u8
54 return 0
55}
56// green rectangle outline (nx_image_set bounds-checks, so it is safe)
57func draw_box(img: *Image, x0: i64, y0: i64, x1: i64, y1: i64) -> i64 {
58 var x: i64 = x0
59 while x <= x1 {
60 nx_image_set(img, x, y0, 0, 0); nx_image_set(img, x, y0, 1, 255); nx_image_set(img, x, y0, 2, 0)
61 nx_image_set(img, x, y1, 0, 0); nx_image_set(img, x, y1, 1, 255); nx_image_set(img, x, y1, 2, 0)
62 x = x + 1
63 }
64 var y: i64 = y0
65 while y <= y1 {
66 nx_image_set(img, x0, y, 0, 0); nx_image_set(img, x0, y, 1, 255); nx_image_set(img, x0, y, 2, 0)
67 nx_image_set(img, x1, y, 0, 0); nx_image_set(img, x1, y, 1, 255); nx_image_set(img, x1, y, 2, 0)
68 y = y + 1
69 }
70 return 0
71}
72
73func main() -> i64 {
74 let szp: *i64 = sys_mmap(16) as *i64
75 let buf: *u8 = sys_read_file("knowledge/staging/media/idx_in.txt\x00" as *u8, szp)
76 if (buf as i64) == 0 { gp("nx_skin_diag: no idx_in.txt\n\x00" as *u8); return 1 }
77 let len: i64 = szp[0]
78 let pbuf: *u8 = sys_mmap(PRESENT_MAGIC_4096)
79 let mpath: *u8 = sys_mmap(PRESENT_MAGIC_4096)
80 var idx: i64 = 0
81 var i: i64 = 0
82 while i < len {
83 var j: i64 = i
84 while j < len && (buf[j] as i64) != 10 { j = j + 1 }
85 var end: i64 = j
86 if end > i && (buf[end - 1] as i64) == 13 { end = end - 1 }
87 let ll: i64 = end - i
88 if ll > 0 {
89 var k: i64 = 0
90 while k < ll && k < PRESENT_MAGIC_4095 { pbuf[k] = buf[i + k]; k = k + 1 }
91 pbuf[k] = 0 as u8
92 // read + decode
93 let zp: *i64 = sys_mmap(16) as *i64
94 let fb: *u8 = sys_read_file(pbuf, zp)
95 var skip: i64 = 0
96 if (fb as i64) == 0 { skip = 1 }
97 if skip == 0 { if zp[0] < 8 { skip = 1 } }
98 if skip == 0 { if (fb[0] as i64) != 137 { skip = 1 } }
99 if skip == 0 {
100 let r: *NxPngResult = nx_png_decode(fb, zp[0])
101 if (r as i64) == 0 { skip = 1 }
102 if skip == 0 { if r.error_code != NX_PNG_OK { skip = 1 } }
103 if skip == 0 {
104 let img: *Image = nx_mindex_png_to_image(r)
105 let w: i64 = img.width
106 let h: i64 = img.height
107 let mask: *Image = nx_image_alloc(w, h, 3)
108 var sc: i64 = 0
109 var y: i64 = 0
110 while y < h {
111 var x: i64 = 0
112 while x < w {
113 let rr: i64 = nx_image_get(img, x, y, 0)
114 let gg: i64 = nx_image_get(img, x, y, 1)
115 let bb2: i64 = nx_image_get(img, x, y, 2)
116 if nx_skin_is_pixel(rr, gg, bb2) == 1 {
117 nx_image_set(mask, x, y, 0, 255)
118 nx_image_set(mask, x, y, 1, 0)
119 nx_image_set(mask, x, y, 2, 255)
120 sc = sc + 1
121 }
122 if nx_skin_is_pixel(rr, gg, bb2) != 1 {
123 let lum: i64 = (rr + gg + bb2) / 6
124 nx_image_set(mask, x, y, 0, lum)
125 nx_image_set(mask, x, y, 1, lum)
126 nx_image_set(mask, x, y, 2, lum)
127 }
128 x = x + 1
129 }
130 y = y + 1
131 }
132 let skinpm: i64 = sc * 1000 / (w * h)
133 // R2-refine: largest connected skin blob -> localized box
134 let bout: *i64 = sys_mmap(128) as *i64
135 nx_blob_largest(img, bout)
136 let gridn: i64 = bout[7]
137 var bx0: i64 = 0
138 var by0: i64 = 0
139 var bx1: i64 = 0
140 var by1: i64 = 0
141 if bout[0] > 0 {
142 bx0 = bout[1] * w / gridn
143 by0 = bout[2] * h / gridn
144 bx1 = (bout[3] + 1) * w / gridn - 1
145 by1 = (bout[4] + 1) * h / gridn - 1
146 draw_box(mask, bx0, by0, bx1, by1)
147 }
148 build_mask_path(mpath, idx)
149 bmp_write(mask, mpath)
150 gp(" img\x00" as *u8); gn(idx); gp(" \x00" as *u8); gn(w); gp("x\x00" as *u8); gn(h)
151 gp(" skin=\x00" as *u8); gn(skinpm); gp("permille blob_cells=\x00" as *u8); gn(bout[0])
152 gp(" box_px=[\x00" as *u8); gn(bx0); gp(",\x00" as *u8); gn(by0); gp("..\x00" as *u8); gn(bx1); gp(",\x00" as *u8); gn(by1); gp("]\x00" as *u8)
153 gp(" -> mask_\x00" as *u8); gn(idx); gp(".bmp\n\x00" as *u8)
154 idx = idx + 1
155 }
156 }
157 }
158 i = j + 1
159 }
160 gp("nx_skin_diag wrote \x00" as *u8); gn(idx); gp(" mask BMPs to knowledge/staging/media/\n\x00" as *u8)
161 return 0
162}