nx_texture_test.nx source
↩ module page · 138 lines · 5402 B
1// nx_texture_test.nx -- smoke for V5 texture primitives.
2
3import "syscalls.nx"
4import "nx_image.nx"
5import "nx_texture.nx"
6
7func main() -> i64 {
8 // === Test 1: GLCM on a UNIFORM image (all 128) ===
9 // Quantized: 128 >> 5 = 4. All pairs are (4, 4), so glcm[36] == total.
10 let img1: *Image = nx_image_alloc(8, 8, 1)
11 var y: i64 = 0
12 while y < 8 {
13 var x: i64 = 0
14 while x < 8 {
15 nx_image_set(img1, x, y, 0, 128)
16 x = x + 1
17 }
18 y = y + 1
19 }
20 let glcm: *i64 = (sys_mmap(64 * 8)) as *i64
21 nx_texture_glcm(img1, 1, 0, glcm)
22 // Total horizontal pairs: 7 cols offset * 8 rows = 56
23 let total1: i64 = nx_texture_glcm_total(glcm)
24 if total1 != 56 { return 1 }
25 if glcm[4 * 8 + 4] != 56 { return 2 }
26 if glcm[0] != 0 { return 3 }
27 // Contrast on uniform = 0
28 if nx_texture_contrast(glcm) != 0 { return 4 }
29 // Energy on uniform = max (1024 in Q10)
30 if nx_texture_energy(glcm) != 1024 { return 5 }
31 // Homogeneity on uniform = max (1024 in Q10)
32 if nx_texture_homogeneity(glcm) != 1024 { return 6 }
33
34 // === Test 2: GLCM on CHECKERBOARD (alternating 0 and 255) ===
35 // Quantized: 0 >> 5 = 0, 255 >> 5 = 7.
36 // Horizontal pairs all transition between 0 and 7.
37 let img2: *Image = nx_image_alloc(8, 8, 1)
38 var y2: i64 = 0
39 while y2 < 8 {
40 var x2: i64 = 0
41 while x2 < 8 {
42 var v: i64 = 0
43 let parity: i64 = (x2 + y2) - ((x2 + y2) / 2) * 2
44 if parity == 1 { v = 255 }
45 nx_image_set(img2, x2, y2, 0, v)
46 x2 = x2 + 1
47 }
48 y2 = y2 + 1
49 }
50 let glcm2: *i64 = (sys_mmap(64 * 8)) as *i64
51 nx_texture_glcm(img2, 1, 0, glcm2)
52 // Should only be glcm[0*8+7]=glcm[7] and glcm[7*8+0]=glcm[56] populated.
53 let total2: i64 = nx_texture_glcm_total(glcm2)
54 if total2 != 56 { return 10 }
55 if glcm2[7] + glcm2[56] != 56 { return 11 }
56 // Contrast on checkerboard: (0-7)^2 = 49, so contrast_raw = 49 * 56,
57 // contrast_q10 = 49 * 1024 = 50176
58 let c2: i64 = nx_texture_contrast(glcm2)
59 if c2 < 49000 { return 12 }
60 if c2 > 51000 { return 13 }
61 // Energy on checkerboard: 2 bins with 28 each, energy = 2*28^2/56^2 = 1568/3136 = 0.5
62 // -> Q10 = 512
63 let e2: i64 = nx_texture_energy(glcm2)
64 if e2 < 480 { return 14 }
65 if e2 > 540 { return 15 }
66 // Homogeneity on checkerboard: pairs at (0,7) and (7,0), denom = 1 + 49 = 50
67 // hom = 56/(56*50) = 1/50 -> Q10 = 20.48, allow [15, 30]
68 let h2: i64 = nx_texture_homogeneity(glcm2)
69 if h2 < 15 { return 16 }
70 if h2 > 30 { return 17 }
71
72 // === Test 3: LBP pixel on uniform image ===
73 // Center = 128, all neighbors = 128. Each "neighbor >= center"
74 // is TRUE, so code = 1+2+4+8+16+32+64+128 = 255.
75 if nx_texture_lbp_pixel(img1, 4, 4) != 255 { return 20 }
76
77 // === Test 4: LBP pixel at bright peak ===
78 // Center = 255, all neighbors = 0. Code = 0.
79 let img3: *Image = nx_image_alloc(8, 8, 1)
80 nx_image_set(img3, 4, 4, 0, 255)
81 if nx_texture_lbp_pixel(img3, 4, 4) != 0 { return 21 }
82
83 // === Test 5: LBP pixel at dark hole ===
84 // All neighbors brighter than center. Code = 255 (all 8 bits set).
85 let img4: *Image = nx_image_alloc(8, 8, 1)
86 var ly: i64 = 0
87 while ly < 8 {
88 var lx: i64 = 0
89 while lx < 8 {
90 nx_image_set(img4, lx, ly, 0, 200)
91 lx = lx + 1
92 }
93 ly = ly + 1
94 }
95 nx_image_set(img4, 4, 4, 0, 100) // dark center
96 if nx_texture_lbp_pixel(img4, 4, 4) != 255 { return 22 }
97
98 // === Test 6: LBP image + histogram ===
99 let lbp: *Image = nx_texture_lbp_image(img1) // uniform -> code 255 everywhere
100 let hist: *i64 = (sys_mmap(256 * 8)) as *i64
101 nx_texture_lbp_histogram(lbp, 1, 1, 7, 7, hist)
102 // Interior 6x6 = 36 pixels, all should be code 255 on uniform image.
103 if hist[255] != 36 { return 30 }
104 // Other bins should be 0.
105 if hist[0] != 0 { return 31 }
106 if hist[128] != 0 { return 32 }
107
108 // === Test 7: Direction sensitivity of GLCM ===
109 // Horizontal stripes -- horizontal GLCM(1,0) should be near-uniform
110 // along diagonal; vertical GLCM(0,1) should have big off-diagonal.
111 let img5: *Image = nx_image_alloc(8, 8, 1)
112 var sy: i64 = 0
113 while sy < 8 {
114 var sx: i64 = 0
115 while sx < 8 {
116 var v: i64 = 0
117 // Even rows = 0, odd rows = 255
118 let parity_y: i64 = sy - (sy / 2) * 2
119 if parity_y == 1 { v = 255 }
120 nx_image_set(img5, sx, sy, 0, v)
121 sx = sx + 1
122 }
123 sy = sy + 1
124 }
125 let glcm_h: *i64 = (sys_mmap(64 * 8)) as *i64
126 let glcm_v: *i64 = (sys_mmap(64 * 8)) as *i64
127 nx_texture_glcm(img5, 1, 0, glcm_h) // along stripes
128 nx_texture_glcm(img5, 0, 1, glcm_v) // across stripes
129 // Horizontal: all pairs same row -> all same value -> on diagonal
130 let ch: i64 = nx_texture_contrast(glcm_h)
131 let cv: i64 = nx_texture_contrast(glcm_v)
132 // Contrast across stripes >> contrast along stripes.
133 if cv <= ch { return 40 }
134 // Sanity: along stripes contrast should be 0 (all pairs identical).
135 if ch != 0 { return 41 }
136
137 return 0
138}