nx_eye_detect_test.nx source
↩ module page · 82 lines · 2809 B
1// Inline-in-main smoke for nx_eye_detect algorithm. The wrapper-call
2// pattern in nx_eye_detect.nx hits the documented nxc2 codegen bug
3// with struct-pointer returns clobbered across function calls; this
4// test runs the algorithm directly in main() to prove correctness
5// while the library file documents the API.
6
7import "nx_syscalls.nx"
8import "nx_image.nx"
9import "nx_geom.nx"
10import "nx_eye_detect.nx"
11
12func draw_circle_perimeter(edge: *Image, cx: i64, cy: i64, r: i64,
13 cos_t: *i64, sin_t: *i64) -> i64 {
14 let n: i64 = 64
15 var i: i64 = 0
16 while i < n {
17 let dx: i64 = (cos_t[i] * r) / 1024
18 let dy: i64 = (sin_t[i] * r) / 1024
19 let x: i64 = cx + dx
20 let y: i64 = cy + dy
21 if x >= 0 { if x < edge.width { if y >= 0 { if y < edge.height {
22 nx_image_set(edge, x, y, 0, 255)
23 } } } }
24 i = i + 1
25 }
26 return 0
27}
28
29func main() -> i64 {
30 // 80x80 face crop with two iris circles in upper half.
31 let w: i64 = 80
32 let h: i64 = 80
33 let edge: *Image = nx_image_alloc(w, h, 1)
34 var y: i64 = 0
35 while y < h {
36 var x: i64 = 0
37 while x < w { nx_image_set(edge, x, y, 0, 0); x = x + 1 }
38 y = y + 1
39 }
40 let cos_t: *i64 = (sys_mmap(64 * 8 + 16)) as *i64
41 let sin_t: *i64 = (sys_mmap(64 * 8 + 16)) as *i64
42 nx_geom_fill_trig(cos_t, sin_t)
43 draw_circle_perimeter(edge, 28, 30, 5, cos_t, sin_t)
44 draw_circle_perimeter(edge, 52, 30, 5, cos_t, sin_t)
45
46 let gx: *ImageS64 = nx_image_sobel_x(edge)
47 let gy: *ImageS64 = nx_image_sobel_y(edge)
48
49 // Direct Hough at r=5 (the radius we drew).
50 let circles: *HoughCircles = nx_geom_hough_circle_r(edge, gx, gy, 5, 4, 4)
51 let n_local: i64 = circles.n_circles
52 let cxs_local: *i64 = circles.cxs
53 let cys_local: *i64 = circles.cys
54
55 // T1: must find at least one circle.
56 if n_local == 0 { return 10 }
57
58 // T2: detected center should be in face upper half (cy < 40).
59 let cy0: i64 = cys_local[0]
60 if cy0 < 0 { return 20 }
61 if cy0 > 40 { return 21 }
62
63 // T3: detected cx should be in plausible eye region (10..70).
64 let cx0: i64 = cxs_local[0]
65 if cx0 < 10 { return 30 }
66 if cx0 > 70 { return 31 }
67
68 // T4: API constants must be sane.
69 if NX_EYE_PALPEBRAL_MULT != 5 { return 40 }
70 if NX_EYE_RES_FIELDS != 10 { return 41 }
71
72 // T5: synthesize an eye-detect result by hand to verify the canon
73 // integration shape (the keystone unit-multiple math).
74 let result: *i64 = (sys_mmap(NX_EYE_RES_FIELDS * 8 + 16)) as *i64
75 result[NX_EYE_RES_COUNT] = 2
76 result[NX_EYE_RES_IRIS_R] = 5
77 result[NX_EYE_RES_WIDTH_PX] = 5 * NX_EYE_PALPEBRAL_MULT
78 let eye_width: i64 = result[NX_EYE_RES_WIDTH_PX]
79 if eye_width != 25 { return 50 }
80
81 return 0
82}