code wiki / (root) / nx_eye_detect_test.nx

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}