code wiki / (root) / nx_imgquery.nx

nx_imgquery.nx source

↩ module page · 51 lines · 2314 B

1// nx_imgquery.nx -- HYBRID reverse-image query: two complementary tiers over one corpus. 2// COPY tier -- dHash Hamming <= copy_thresh: exact/near DUPLICATES (TinEye-style, what dHash is for). 3// SIMILAR tier -- imgsig (visdesc structure + colordesc color) L1 nearest: VISUALLY-ALIKE images that 4// are NOT byte-copies (Google-style). dHash is colorblind and structure-blind to scale, 5// so the similar tier surfaces matches the copy tier structurally cannot. 6// Caller holds parallel arrays: dhashes[i] (i64), sigs[i] (i64 = pointer to that item's 112-dim imgsig), 7// pays[i] (payload/docid). Linear scan here (correct + simple); nx_phash_index (BK-tree) is the scale tier. 8// Composes nx_imgsig + nx_phash -- ZERO new ranking math. license_tier: ORIGINAL 9import "nx_imgsig.nx" 10import "nx_phash.nx" 11 12// COPY tier: payloads whose dHash is within copy_thresh Hamming of the query. returns count; 13// out[i]=payload, out_ham[i]=Hamming. 14func nx_imgquery_copies(q_dhash: i64, dhashes: *i64, pays: *i64, n: i64, copy_thresh: i64, out: *i64, out_ham: *i64) -> i64 { 15 var m: i64 = 0 16 var i: i64 = 0 17 while i < n { 18 let hh: i64 = nx_simhash_hamming(q_dhash, dhashes[i]) 19 if hh <= copy_thresh { out[m] = pays[i]; out_ham[m] = hh; m = m + 1 } 20 i = i + 1 21 } 22 return m 23} 24 25// SIMILAR tier: the topk corpus items by ascending imgsig L1 to the query (repeated-min, n small). 26// out[i]=payload, out_l1[i]=imgsig L1. `taken` is caller scratch of length >= n. 27func nx_imgquery_similar(q_sig: *i64, sigs: *i64, pays: *i64, n: i64, topk: i64, out: *i64, out_l1: *i64, taken: *i64) -> i64 { 28 var i: i64 = 0 29 while i < n { taken[i] = 0; i = i + 1 } 30 var m: i64 = 0 31 while m < topk { 32 if m >= n { return m } 33 var best: i64 = 0 - 1 34 var bestl: i64 = 0 35 var j: i64 = 0 36 while j < n { 37 if taken[j] == 0 { 38 let sj: *i64 = sigs[j] as *i64 39 let l1: i64 = nx_imgsig_l1(q_sig, sj) 40 if best < 0 { best = j; bestl = l1 } else { if l1 < bestl { best = j; bestl = l1 } } 41 } 42 j = j + 1 43 } 44 if best < 0 { return m } 45 taken[best] = 1 46 out[m] = pays[best] 47 out_l1[m] = bestl 48 m = m + 1 49 } 50 return m 51}