code wiki / (root) / nx_haar_cascade.nx

nx_haar_cascade.nx source

↩ module page · 59 lines · 2472 B

1// nx_haar_cascade.nx -- Viola-Jones attentional cascade EVALUATOR (R-FACE-2). 2// The detector engine: a weak classifier is a Haar feature + threshold + 3// polarity; a stage sums weighted weak votes vs a stage threshold; the cascade 4// runs stages in order and EARLY-REJECTS the moment any stage fails (so the 5// vast non-object majority is discarded after 1-2 cheap stages). 6// 7// This evaluates a GIVEN cascade. The cascade PARAMETERS (thresholds/polarities/ 8// alphas/stage thresholds) come from TRAINING (AdaBoost over a labeled face / 9// non-face set) -- a separate data-dependent rung. This rung is the machinery, 10// validated with a hand-built toy cascade. 11// 12// Layout (caller-supplied flat i64 arrays): 13// weak row (8 i64): [kind, x, y, w, h, threshold, polarity(+1/-1), alpha] 14// stage row (3 i64): [weak_offset(in rows), weak_count, stage_threshold] 15// 16// genealogy_id: viola_jones_2001_attentional_cascade + freund_schapire_adaboost_1997 17// lineage_id: weak_classifier + boosted_stage + early_reject_cascade 18// license_tier: ORIGINAL 19import "syscalls.nx" 20import "nx_image.nx" 21import "nx_integral.nx" 22import "nx_haar.nx" 23 24const NX_WEAK_FIELDS: i64 = 8 25const NX_STAGE_FIELDS: i64 = 3 26 27// One weak classifier: 1 if the feature votes "object", else 0. 28// vote = (polarity * feature) < (polarity * threshold) 29func nx_weak_eval(ii: *IntegralImage, weak: *i64) -> i64 { 30 let f: i64 = nx_haar_eval(ii, weak[0], weak[1], weak[2], weak[3], weak[4]) 31 let pol: i64 = weak[6] 32 if pol * f < pol * weak[5] { return 1 } 33 return 0 34} 35 36// One stage: pass(1)/fail(0). Pass if sum of alpha over firing weaks >= stage_thresh. 37func nx_stage_eval(ii: *IntegralImage, weaks: *i64, n: i64, stage_thresh: i64) -> i64 { 38 var s: i64 = 0 39 var i: i64 = 0 40 while i < n { 41 let row: *i64 = (weaks as i64 + i * NX_WEAK_FIELDS * 8) as *i64 42 if nx_weak_eval(ii, row) == 1 { s = s + row[7] } 43 i = i + 1 44 } 45 if s >= stage_thresh { return 1 } 46 return 0 47} 48 49// Full cascade: 1 if ALL stages pass (early reject on first failure). 50func nx_haar_cascade_eval(ii: *IntegralImage, stages: *i64, n_stages: i64, weaks: *i64) -> i64 { 51 var st: i64 = 0 52 while st < n_stages { 53 let meta: *i64 = (stages as i64 + st * NX_STAGE_FIELDS * 8) as *i64 54 let wrow: *i64 = (weaks as i64 + meta[0] * NX_WEAK_FIELDS * 8) as *i64 55 if nx_stage_eval(ii, wrow, meta[1], meta[2]) == 0 { return 0 } 56 st = st + 1 57 } 58 return 1 59}