code wiki / (root) / nx_pose_estimate.nx

nx_pose_estimate.nx source

↩ module page · 75 lines · 3249 B

1// nx_pose_estimate.nx -- LEARNED pose localization from an image (roadmap R2 v0, the video->POSE keystone gap). 2// Sovereign + deterministic, the text2motion playbook: a silhouette (z-buffer occupancy grid) -> a PERCEPTRON 3// that classifies WHERE a keypoint is (a coarse region). Trained on rendered rig poses (we generate the data), 4// proven by HELD-OUT generalization. Honest ceiling: coarse region-classification of ONE joint on OUR-render 5// silhouettes; SOTA = precise full-body keypoints from real video via a trained CNN (OpenPose/MoveNet). The 6// architecture (image feature -> learned classifier -> keypoint) is the real thing at small scale. ORIGINAL 7import "nx_syscalls.nx" 8const K_MAGIC_1900000000: i64 = 1900000000 9 10// downsample the figure silhouette (zb > FAR sentinel = figure) to a gw*gh occupancy grid (each 0..256). 11func pe_occupancy(zb: *i64, w: i64, h: i64, gw: i64, gh: i64, occ: *i64) -> i64 { 12 var cy: i64 = 0 13 while cy < gh { 14 var cx: i64 = 0 15 while cx < gw { 16 let x0: i64 = cx * w / gw; let x1: i64 = (cx + 1) * w / gw 17 let y0: i64 = cy * h / gh; let y1: i64 = (cy + 1) * h / gh 18 var cnt: i64 = 0; var tot: i64 = 0 19 var y: i64 = y0 20 while y < y1 { 21 var x: i64 = x0 22 while x < x1 { tot = tot + 1; if zb[y * w + x] > (0 - K_MAGIC_1900000000) { cnt = cnt + 1 } x = x + 1 } 23 y = y + 1 24 } 25 var v: i64 = 0 26 if tot > 0 { v = cnt * 256 / tot } 27 occ[cy * gw + cx] = v 28 cx = cx + 1 29 } 30 cy = cy + 1 31 } 32 return 0 33} 34// perceptron score for class r over ncell features (+1 bias appended by caller as occ[ncell]=256). 35func pe_score(W: *i64, r: i64, occ: *i64, nfeat: i64) -> i64 { 36 var s: i64 = 0; var c: i64 = 0 37 while c < nfeat { s = s + W[r * nfeat + c] * occ[c]; c = c + 1 } 38 return s 39} 40func pe_predict(W: *i64, occ: *i64, nfeat: i64, nr: i64) -> i64 { 41 var best: i64 = 0; var bs: i64 = pe_score(W, 0, occ, nfeat) 42 var r: i64 = 1 43 while r < nr { let s: i64 = pe_score(W, r, occ, nfeat); if s > bs { bs = s; best = r } r = r + 1 } 44 return best 45} 46// train by the perceptron rule over nsamp (occ-row, label) pairs for `epochs`; returns last-epoch mistakes. 47// occs = nsamp*nfeat, labels = nsamp. W = nr*nfeat (zeroed here). 48func pe_train(W: *i64, occs: *i64, labels: *i64, nsamp: i64, nfeat: i64, nr: i64, epochs: i64) -> i64 { 49 var i: i64 = 0 50 while i < nr * nfeat { W[i] = 0; i = i + 1 } 51 var last: i64 = 0 52 var e: i64 = 0 53 while e < epochs { 54 var mist: i64 = 0 55 var n: i64 = 0 56 while n < nsamp { 57 let occ: *i64 = (occs as i64 + n * nfeat * 8) as *i64 58 let pred: i64 = pe_predict(W, occ, nfeat, nr) 59 let lab: i64 = labels[n] 60 if pred != lab { 61 mist = mist + 1 62 var c: i64 = 0 63 while c < nfeat { 64 W[lab * nfeat + c] = W[lab * nfeat + c] + occ[c] 65 W[pred * nfeat + c] = W[pred * nfeat + c] - occ[c] 66 c = c + 1 67 } 68 } 69 n = n + 1 70 } 71 last = mist 72 e = e + 1 73 } 74 return last 75}