nx_haar.nx source
↩ module page · 58 lines · 2619 B
1// nx_haar.nx -- Haar-like rectangle features (R-FACE-1), evaluated in O(1) on
2// the integral image (nx_integral). These are the weak-feature primitives of a
3// Viola-Jones cascade: a feature value is (sum of "white" rects) - (sum of
4// "black" rects), each rect summed by four integral lookups.
5//
6// EDGE_H : [white | black] left-right contrast (vertical edge)
7// EDGE_V : [white / black] top-bottom contrast (horizontal edge)
8// LINE_H : [white|black|white] a dark vertical bar between light
9// FOUR : 2x2 checker (TL,BR)-(TR,BL) diagonal contrast
10//
11// Raw integer value (no per-window variance normalization yet -- that is a
12// later rung; the cascade adds it). Pure i64 over nx_integral.
13//
14// genealogy_id: viola_jones_2001 + papageorgiou_haar_wavelets_1998 (record-hint)
15// lineage_id: haar_rectangle_feature + integral_image_o1
16// license_tier: ORIGINAL
17import "syscalls.nx"
18import "nx_image.nx"
19import "nx_integral.nx"
20
21const NX_HAAR_EDGE_H: i64 = 0
22const NX_HAAR_EDGE_V: i64 = 1
23const NX_HAAR_LINE_H: i64 = 2
24const NX_HAAR_FOUR: i64 = 3
25
26// Evaluate a Haar feature of `kind` in the window rect (x,y) size (w,h).
27// Returns whiteSum - blackSum (raw i64).
28func nx_haar_eval(ii: *IntegralImage, kind: i64, x: i64, y: i64, w: i64, h: i64) -> i64 {
29 if kind == NX_HAAR_EDGE_H {
30 let hw: i64 = w / 2
31 let left: i64 = nx_integral_rect_sum(ii, x, y, x + hw - 1, y + h - 1)
32 let right: i64 = nx_integral_rect_sum(ii, x + hw, y, x + w - 1, y + h - 1)
33 return left - right
34 }
35 if kind == NX_HAAR_EDGE_V {
36 let hh: i64 = h / 2
37 let top: i64 = nx_integral_rect_sum(ii, x, y, x + w - 1, y + hh - 1)
38 let bot: i64 = nx_integral_rect_sum(ii, x, y + hh, x + w - 1, y + h - 1)
39 return top - bot
40 }
41 if kind == NX_HAAR_LINE_H {
42 let tw: i64 = w / 3
43 let l: i64 = nx_integral_rect_sum(ii, x, y, x + tw - 1, y + h - 1)
44 let c: i64 = nx_integral_rect_sum(ii, x + tw, y, x + 2 * tw - 1, y + h - 1)
45 let r: i64 = nx_integral_rect_sum(ii, x + 2 * tw, y, x + 3 * tw - 1, y + h - 1)
46 return (l + r) - 2 * c
47 }
48 if kind == NX_HAAR_FOUR {
49 let hw: i64 = w / 2
50 let hh: i64 = h / 2
51 let tl: i64 = nx_integral_rect_sum(ii, x, y, x + hw - 1, y + hh - 1)
52 let tr: i64 = nx_integral_rect_sum(ii, x + hw, y, x + w - 1, y + hh - 1)
53 let bl: i64 = nx_integral_rect_sum(ii, x, y + hh, x + hw - 1, y + h - 1)
54 let br: i64 = nx_integral_rect_sum(ii, x + hw, y + hh, x + w - 1, y + h - 1)
55 return (tl + br) - (tr + bl)
56 }
57 return 0
58}