code wiki / (root) / nx_imgkp.nx

nx_imgkp.nx

buildroot/runtime/nx_imgkp.nx

18832 B408 linesdepth 5pulls 7 transitivereach 5 importersview sourcekind library
docsdependenciesstructsconstsfunctions

about

nx_imgkp.nx -- LOCAL FEATURES: FAST corners + BRIEF binary descriptors, integer, deterministic. The global descriptors (dHash, edge-orientation layout) hit a hard ceiling the ruler MEASURED: crop-30pct = 562, letterbox = 656 permille. That ceiling is structural -- a global fingerprint summarises the WHOLE frame, so removing a third of the pixels or padding a border changes it no matter how the summary is computed. TinEye clears exactly this by matching LOCAL regions and then checking they agree GEOMETRICALLY: even if half the picture is gone, the surviving corners still line up under one consistent shift. Every piece here is integer + zero-float + deterministic, which is the whole reason it belongs in the sovereign engine rather than an OpenCV shell-out: * FAST-9 corner test (Rosten & Drummond 2006) -- pure intensity comparisons on a Bresenham circle. * BRIEF-256 descriptor (Calonder 2010) -- 256 intensity-pair comparisons -> a 256-bit string whose distance is popcount Hamming, i.e. the nx_simhash kernel the engine already rides. * A FIXED sampling pattern regenerated from one seed every call, so index-time and query-time descriptors are bit-identical without any stored state. HONEST SCOPE, stated so it is not mistaken for more: plain BRIEF is NOT rotation-invariant. That is deliberate and correct here -- the orientation axis (mirror / quarter-turn) is already owned by the dihedral tier at the global level, and the two classes this rung targets (crop, letterbox) are pure translations. Oriented-BRIEF (ORB) to combine rotation WITH occlusion is a later refinement, filed. PACKED LAYOUT (one image's feature set as a flat i64 block, so it fits the tier vtable's fixed descriptor slot): out[0] = keypoint count; then KP_MAX records of 6 i64 each = [x, y, d0,d1,d2,d3]. genealogy_id: rosten_2006_fast + calonder_2010_brief. license_tier: ORIGINAL

dependencies 2 imports · 1 importers

syscalls.nx nx_simhash.nx nx_imgkp.nx nx_imgsearch_tier.nx

imports: syscalls.nxnx_simhash.nx

imported by: nx_imgsearch_tier.nx

structs

none

consts

29const KP_MAX: i64 = 24 // keypoints kept per image (spatially spread by NMS)
30const KP_WORDS: i64 = 4 // 256-bit BRIEF descriptor = 4 x i64
31const KP_REC: i64 = 6 // per keypoint: x, y, 4 descriptor words
32const KP_PACK: i64 = 145 // 1 + KP_MAX*KP_REC -- the tier idx_dim (UNCHANGED by the pyramid)
33const KP_FAST_N: i64 = 9 // contiguous arc length for a FAST-9 corner
34const KP_FAST_T: i64 = 16 // intensity threshold (of 0..255)
35const KP_PATCH: i64 = 6 // BRIEF samples drawn within +/- this of the keypoint
36const KP_NMS_R: i64 = 3 // non-max suppression radius (spread keypoints out)
37const KP_CAND_PEROCT: i64 = 8192 // per-octave candidate cap
38const KP_CAND_MAX: i64 = 8192 // total candidate cap = KP_CAND_PEROCT * KP_OCTAVES (bounds per-call memory)
39const KP_BRIEF_BITS: i64 = 256
67const KP_OCTAVES: i64 = 1 // INDEX stays single-scale, deliberately -- see above
68const KP_QSCALES: i64 = 5 // query-side scale sweep width
69const KP_QPIXCAP: i64 = 40000000 // skip a sweep scale whose resampled image exceeds this
339const KP_MATCH_MAXHAM: i64 = 96 // absolute Hamming ceiling for a plausible match (of 256 bits)

functions

73func kp_qscale_num(i: i64) -> i64
80func kp_qscale_den(i: i64) -> i64
88func kp_pack_dim() -> i64 { return KP_PACK }
92func kp_circle(cx: *i64, cy: *i64) -> i64
called by 1: nx_imgkp_describe
112func kp_rng(s: *i64) -> i64 { let x: i64 = s[0] * 0x5851F42D4C957F2D + 0x14057B7EF767814F; s[0] = x; return x }
called by 1: kp_brief_pattern
117func kp_brief_pattern(pat: *i64) -> i64
called by 1: nx_imgkp_describe calls 1: kp_rng
137func kp_abs(v: i64) -> i64 { if v < 0 { return 0 - v } return v }
143func kp_is_corner(gray: *u8, w: i64, h: i64, x: i64, y: i64, cx: *i64, cy: *i64, bright: *i64, dark: *i64, score: *i64) -> i64
called by 1: nx_imgkp_describe calls 1: kp_abs
172func kp_brief_at(gray: *u8, w: i64, h: i64, x: i64, y: i64, pat: *i64, desc: *i64) -> i64
called by 1: nx_imgkp_describe
189func kp_downscale(src: *u8, sw: i64, sh: i64, dst: *u8, dw: i64, dh: i64) -> i64
205func kp_oct_dim(o: i64, base: i64) -> i64
called by 1: nx_imgkp_describe
216func nx_imgkp_describe(gray: *u8, w: i64, h: i64, out: *i64) -> i64
324func nx_imgkp_count(pk: *i64) -> i64 { return pk[0] }
327func kp_desc_hamming(pk_a: *i64, ia: i64, pk_b: *i64, ib: i64) -> i64
called by 1: nx_imgkp_match calls 1: nx_simhash_hamming
340func nx_imgkp_match(q: *i64, d: *i64, out_qx: *i64, out_qy: *i64, out_dx: *i64, out_dy: *i64, cap: i64) -> i64
380func nx_imgkp_query_dim() -> i64 { return KP_PACK * KP_QSCALES }
382func nx_imgkp_describe_query(gray: *u8, w: i64, h: i64, out: *i64) -> i64