nx_cam_test.nx source
↩ module page · 106 lines · 3941 B
1// nx_cam_test.nx -- smoke for V9 camera primitives.
2
3import "syscalls.nx"
4import "nx_image.nx"
5import "nx_cam.nx"
6
7func main() -> i64 {
8 // === Test 1: pinhole projection ===
9 // World point (100, 200, 1000), fx=fy=500, cx=cy=256.
10 // u = 500 * 100 / 1000 + 256 = 50 + 256 = 306
11 // v = 500 * 200 / 1000 + 256 = 100 + 256 = 356
12 let u: *i64 = (sys_mmap(8)) as *i64
13 let v: *i64 = (sys_mmap(8)) as *i64
14 nx_cam_pinhole_project(100, 200, 1000, 500, 500, 256, 256, u, v)
15 if u[0] != 306 { return 1 }
16 if v[0] != 356 { return 2 }
17 // Z=0 -> error
18 if nx_cam_pinhole_project(1, 1, 0, 500, 500, 256, 256, u, v) != -1 { return 3 }
19
20 // === Test 2: identity homography preserves points ===
21 let H: *i64 = (sys_mmap(9 * 8)) as *i64
22 nx_cam_homography_identity(H)
23 nx_cam_homography_apply(H, 100, 200, u, v)
24 if u[0] != 100 { return 10 }
25 if v[0] != 200 { return 11 }
26
27 // === Test 3: translation homography ===
28 nx_cam_homography_translate(H, 50, -30)
29 nx_cam_homography_apply(H, 100, 200, u, v)
30 if u[0] != 150 { return 20 }
31 if v[0] != 170 { return 21 }
32
33 // === Test 4: scale homography ===
34 // 2x scale: pass 2 * Q14 = 32768
35 nx_cam_homography_scale(H, 2 * 16384, 2 * 16384)
36 nx_cam_homography_apply(H, 100, 50, u, v)
37 if u[0] != 200 { return 30 }
38 if v[0] != 100 { return 31 }
39
40 // === Test 5: rotation homography (90 degrees) ===
41 // (1, 0) rotated 90 deg around origin -> (0, 1) (y-down convention).
42 // With matrix [cos(90)=0, -sin(90)=-1, 0; 1, 0, 0; 0, 0, 1]:
43 // u' = 0*1 + (-1)*0 + 0 = 0
44 // v' = 1*1 + 0*0 + 0 = 1
45 nx_cam_homography_rotate(H, 90)
46 nx_cam_homography_apply(H, 100, 0, u, v)
47 // Allow small precision slop from Q10 cos/sin.
48 var du: i64 = u[0]
49 if du < 0 { du = -du }
50 if du > 5 { return 40 }
51 if v[0] < 95 { return 41 }
52 if v[0] > 105 { return 42 }
53
54 // === Test 6: image warp with identity preserves image ===
55 let img: *Image = nx_image_alloc(8, 8, 1)
56 var y: i64 = 0
57 while y < 8 {
58 var x: i64 = 0
59 while x < 8 {
60 nx_image_set(img, x, y, 0, x * 16 + y)
61 x = x + 1
62 }
63 y = y + 1
64 }
65 nx_cam_homography_identity(H)
66 let warped_id: *Image = nx_cam_warp_image(img, H)
67 if nx_image_get(warped_id, 3, 5, 0) != nx_image_get(img, 3, 5, 0) { return 50 }
68 if nx_image_get(warped_id, 7, 7, 0) != nx_image_get(img, 7, 7, 0) { return 51 }
69
70 // === Test 7: image warp with translation shifts content ===
71 // H_inv for translation by (2, 1) is translation by (-2, -1).
72 // dst[x, y] = src[x - 2, y - 1] -- so the image shifts RIGHT 2, DOWN 1.
73 nx_cam_homography_translate(H, -2, -1)
74 let warped_t: *Image = nx_cam_warp_image(img, H)
75 // dst[3, 5] should equal src[3 - 2, 5 - 1] = src[1, 4] = 1*16+4 = 20.
76 let v_actual: i64 = nx_image_get(warped_t, 3, 5, 0)
77 let v_expected: i64 = nx_image_get(img, 1, 4, 0)
78 if v_actual != v_expected { return 60 }
79
80 // === Test 8: compose identity * H = H ===
81 let A: *i64 = (sys_mmap(9 * 8)) as *i64
82 let B: *i64 = (sys_mmap(9 * 8)) as *i64
83 let C: *i64 = (sys_mmap(9 * 8)) as *i64
84 nx_cam_homography_identity(A)
85 nx_cam_homography_translate(B, 10, 20)
86 nx_cam_homography_compose(A, B, C)
87 // C should equal B (within precision).
88 var i: i64 = 0
89 while i < 9 {
90 let d: i64 = C[i] - B[i]
91 var ad: i64 = d
92 if ad < 0 { ad = -ad }
93 if ad > 1 { return 70 }
94 i = i + 1
95 }
96
97 // === Test 9: compose translate(5, 0) * translate(3, 0) = translate(8, 0) ===
98 nx_cam_homography_translate(A, 5, 0)
99 nx_cam_homography_translate(B, 3, 0)
100 nx_cam_homography_compose(A, B, C)
101 nx_cam_homography_apply(C, 0, 0, u, v)
102 if u[0] != 8 { return 80 }
103 if v[0] != 0 { return 81 }
104
105 return 0
106}