code wiki / (root) / nx_vitpose_preprocess.nx

nx_vitpose_preprocess.nx source

↩ module page · 60 lines · 2823 B

1// nx_vitpose_preprocess.nx -- image -> ViTPose input tensor: bilinear-resize an RGB image [sh,sw,3] (u8 0-255, 2// interleaved) to dh x dw and ImageNet-normalize into out [1,3,dh,dw] f32 (NCHW): out = (pix/255 - mean_c)/std_c. 3// The resize uses arbitrary-ratio bilinear via INTEGER coordinate math (src coord sy=(oy+0.5)*sh/dh-0.5 = rational 4// with denom 2*dh -> exact int floor + weights, align_corners=False, PyTorch-matching). Reusable for ANY real-image 5// inference (semantic validation of the ViTPose port + running it as a teacher for build-2). license_tier: ORIGINAL 6import "nx_syscalls.nx" 7import "nx_f32.nx" 8import "nx_f32_cvt.nx" 9import "nx_f32_div.nx" 10 11// rgb[(y*sw+x)*3+c] in 0..255 (int). mean/std are f32[3]. out is [1,3,dh,dw] f32 (NCHW). 12func vitpose_resize_normalize(rgb: *i64, sh: i64, sw: i64, dh: i64, dw: i64, mean: *i64, std: *i64, out: *i64) -> i64 { 13 let f255: i64 = nx_i32_to_f32(255) 14 let DENy: i64 = 2 * dh 15 let DENx: i64 = 2 * dw 16 let DEN2f: i64 = nx_i32_to_f32(DENy * DENx) 17 let plane: i64 = dh * dw 18 var oy: i64 = 0 19 while oy < dh { 20 let SY: i64 = (2 * oy + 1) * sh - dh 21 var qy: i64 = SY / DENy 22 var ry: i64 = SY - qy * DENy 23 if ry < 0 { qy = qy - 1; ry = ry + DENy } 24 var y0: i64 = qy; var y1: i64 = qy + 1 25 if y0 < 0 { y0 = 0 } 26 if y0 > sh - 1 { y0 = sh - 1 } 27 if y1 < 0 { y1 = 0 } 28 if y1 > sh - 1 { y1 = sh - 1 } 29 let iwy: i64 = DENy - ry 30 var ox: i64 = 0 31 while ox < dw { 32 let SX: i64 = (2 * ox + 1) * sw - dw 33 var qx: i64 = SX / DENx 34 var rx: i64 = SX - qx * DENx 35 if rx < 0 { qx = qx - 1; rx = rx + DENx } 36 var x0: i64 = qx; var x1: i64 = qx + 1 37 if x0 < 0 { x0 = 0 } 38 if x0 > sw - 1 { x0 = sw - 1 } 39 if x1 < 0 { x1 = 0 } 40 if x1 > sw - 1 { x1 = sw - 1 } 41 let iwx: i64 = DENx - rx 42 let w00: i64 = iwy * iwx; let w01: i64 = iwy * rx; let w10: i64 = ry * iwx; let w11: i64 = ry * rx 43 var c: i64 = 0 44 while c < 3 { 45 let v00: i64 = rgb[(y0*sw + x0)*3 + c] 46 let v01: i64 = rgb[(y0*sw + x1)*3 + c] 47 let v10: i64 = rgb[(y1*sw + x0)*3 + c] 48 let v11: i64 = rgb[(y1*sw + x1)*3 + c] 49 let num: i64 = w00*v00 + w01*v01 + w10*v10 + w11*v11 // integer weighted sum 50 let pixf: i64 = nx_f32_div(nx_i32_to_f32(num), DEN2f) // interpolated pixel value 0..255 51 let scaled: i64 = nx_f32_div(pixf, f255) // /255 52 out[c*plane + oy*dw + ox] = nx_f32_div(nx_f32_sub(scaled, mean[c]), std[c]) 53 c = c + 1 54 } 55 ox = ox + 1 56 } 57 oy = oy + 1 58 } 59 return 0 60}