code wiki / (root) / nx_photomark.nx

nx_photomark.nx source

↩ module page · 155 lines · 11887 B

1// nx_photomark.nx -- CLI over nx_photomark_lib (aesthetictwin AT4 / AT23 / AT30 / AT31, 2026-09-16): landmarks and scale-free 2// face axes MEASURED from a mirrored photograph, written onto a twin card with a side per eye, and the referee that scores 3// the ruler against the outside oracle rows. 4// nx_photomark measure <jpeg|png> -> codec, route, face box, eye bands, both canthi of each eye, roll, tilt per 5// side (raw and roll-corrected), canon ratios, mouth 6// nx_photomark card <slug> <refkey> <jpeg|png> <when> -> measure, then append canthal_tilt L/R, intercanthal_index, 7// intercanthal_eq_fissure and (when the mouth was seen) upper_over_lower_lip 8// nx_photomark referee <oracle-file> [dir] -> every oracle row against the ruler: per-still NME per canthus and a partition; 9// AT44: per mouth landmark too, as the ruler places it and anchored on the 10// oracle's canthi, each with its own partition 11// measure (AT44) also prints the fissure windows and any canthus pinned to one, and the mouth as five landmarks with its named reason 12// exit: 0 ok | 2 usage | 3 unreadable | 4 decode failed | 5 UNMEASURED (no face or no eye pair) | 6 rows exist 13// The cascade route is taken when the two cascade files load (knowledge/fetched/cmp_aesthetictwin_haar_*.xml, beta-only 14// data); otherwise the skin route, and the receipt names the route. Sides follow the image: the eye on the image left is 15// the subject's RIGHT eye; a mirrored still swaps them. A PNG (an estate render, e.g. nx_anat_sov output) reads through 16// the same door as a JPEG still, so one ruler measures the reference and the twin; the receipt names the codec (1 JPEG, 2 PNG). 17// license_tier: ORIGINAL No hw writes (Rule 26). 18import "nx_syscalls.nx" 19import "nx_photomark_lib.nx" 20 21const PMC_EXIT_USAGE: i64 = 2 22const PMC_EXIT_READ: i64 = 3 23const PMC_EXIT_DECODE: i64 = 4 24const PMC_EXIT_UNMEASURED: i64 = 5 25const PMC_EXIT_EXISTS: i64 = 6 26const PMC_ARGC_MEASURE: i64 = 3 27const PMC_ARGC_CARD: i64 = 6 28const PMC_ARGC_REFEREE: i64 = 3 29const PMC_ARGC_REFEREE_DIR: i64 = 4 30const PMC_I64: i64 = 8 31 32func pmc_usage() -> i64 { 33 ri_puts("usage: nx_photomark measure <jpeg|png> | card <slug> <refkey> <jpeg|png> <when> | referee <oracle-file> [dir]\n" as *u8) 34 return PMC_EXIT_USAGE 35} 36func pmc_kv(k: *u8, v: i64) -> i64 { ri_puts(k); ri_putn(v); return 0 } 37func pmc_report(path: *u8, res: *i64) -> i64 { 38 ri_puts("PHOTOMARK file=" as *u8); ri_puts(path) 39 pmc_kv(" w=" as *u8, res[PM_R_W]); pmc_kv(" h=" as *u8, res[PM_R_H]); pmc_kv(" codec=" as *u8, res[PM_R_CODEC]); pmc_kv(" route=" as *u8, res[PM_R_ROUTE]); pmc_kv(" cell=" as *u8, res[PM_R_CELL]) 40 pmc_kv(" face=" as *u8, res[PM_R_FACE]); pmc_kv(" face_cells=" as *u8, res[PM_R_FACE_CELLS]); pmc_kv(" face_votes=" as *u8, res[PM_R_FVOTES]) 41 pmc_kv(" face_box=" as *u8, res[PM_R_FX0]); pmc_kv("," as *u8, res[PM_R_FY0]); pmc_kv("," as *u8, res[PM_R_FX1]); pmc_kv("," as *u8, res[PM_R_FY1]) 42 pmc_kv(" dark_blobs=" as *u8, res[PM_R_BLOBS]); pmc_kv(" blobs_capped=" as *u8, res[PM_R_BLOBS_CAPPED]) 43 pmc_kv(" head_box=" as *u8, res[PM_R_HX0]); pmc_kv("," as *u8, res[PM_R_HY0]); pmc_kv("," as *u8, res[PM_R_HX1]); pmc_kv("," as *u8, res[PM_R_HY1]) 44 pmc_kv(" eye_band_R=" as *u8, res[PM_R_EX0]); pmc_kv("," as *u8, res[PM_R_EY0]); pmc_kv("," as *u8, res[PM_R_EX1]); pmc_kv("," as *u8, res[PM_R_EY1]) 45 pmc_kv(" eye_band_L=" as *u8, res[PM_R_LX0]); pmc_kv("," as *u8, res[PM_R_LY0]); pmc_kv("," as *u8, res[PM_R_LX1]); pmc_kv("," as *u8, res[PM_R_LY1]) 46 pmc_kv(" eye_votes=" as *u8, res[PM_R_EYE_VOTES_R]); pmc_kv("," as *u8, res[PM_R_EYE_VOTES_L]) 47 pmc_kv(" eyes=" as *u8, res[PM_R_EYES]); pmc_kv(" pair_fail=" as *u8, res[PM_R_PAIR_FAIL]) 48 pmc_kv(" fissure_window_R=" as *u8, res[PM_R_EYE_WX0]); pmc_kv("," as *u8, res[PM_R_EYE_WX1]); pmc_kv(" fissure_window_L=" as *u8, res[PM_R_EYE_LWX0]); pmc_kv("," as *u8, res[PM_R_EYE_LWX1]) 49 pmc_kv(" pinned_bits=" as *u8, res[PM_R_PINNED]) 50 ri_puts("\n" as *u8) 51 if res[PM_R_ROUTE] == PM_ROUTE_SKIN { 52 ri_puts("PHOTOMARK top_blobs(x0,y0,x1,y1:cells)" as *u8) 53 var tb: i64 = 0 54 while tb < PM_TOP_BLOBS { let sl: i64 = PM_R_TB + tb * PM_TB_FIELDS; if res[sl + 4] > 0 { pmc_kv(" b=" as *u8, res[sl]); pmc_kv("," as *u8, res[sl + 1]); pmc_kv("," as *u8, res[sl + 2]); pmc_kv("," as *u8, res[sl + 3]); pmc_kv(":" as *u8, res[sl + 4]) } tb = tb + 1 } 55 ri_puts("\n" as *u8) 56 } 57 if res[PM_R_EYES] == 2 { 58 ri_puts("PHOTOMARK canthi(image x,y; sides by the image, unmirrored assumed)" as *u8) 59 pmc_kv(" R_lateral=" as *u8, res[PM_R_RLAT_X]); pmc_kv("," as *u8, res[PM_R_RLAT_Y]) 60 pmc_kv(" R_medial=" as *u8, res[PM_R_RMED_X]); pmc_kv("," as *u8, res[PM_R_RMED_Y]) 61 pmc_kv(" L_medial=" as *u8, res[PM_R_LMED_X]); pmc_kv("," as *u8, res[PM_R_LMED_Y]) 62 pmc_kv(" L_lateral=" as *u8, res[PM_R_LLAT_X]); pmc_kv("," as *u8, res[PM_R_LLAT_Y]) 63 pmc_kv(" eye_pixels_R=" as *u8, res[PM_R_EYE_PIX_R]); pmc_kv(" eye_pixels_L=" as *u8, res[PM_R_EYE_PIX_L]) 64 ri_puts("\n" as *u8) 65 ri_puts("PHOTOMARK axes" as *u8) 66 pmc_kv(" roll_deg10=" as *u8, res[PM_R_ROLL]) 67 pmc_kv(" canthal_tilt_R_deg10=" as *u8, res[PM_R_TILT_R]); pmc_kv(" canthal_tilt_L_deg10=" as *u8, res[PM_R_TILT_L]) 68 pmc_kv(" tilt_R_raw_deg10=" as *u8, res[PM_R_TILT_R_RAW]); pmc_kv(" tilt_L_raw_deg10=" as *u8, res[PM_R_TILT_L_RAW]) 69 pmc_kv(" fissure_R_px=" as *u8, res[PM_R_FISSURE_R]); pmc_kv(" fissure_L_px=" as *u8, res[PM_R_FISSURE_L]); pmc_kv(" tilt_err_deg10=" as *u8, res[PM_R_TILT_ERR]); pmc_kv(" tilt_row_ok=" as *u8, res[PM_R_TILT_OK]) 70 pmc_kv(" intercanthal_index_permil=" as *u8, res[PM_R_ICI]); pmc_kv(" intercanthal_eq_fissure_permil=" as *u8, res[PM_R_ICF]) 71 pmc_kv(" mouth=" as *u8, res[PM_R_MOUTH]); ri_puts(" mouth_why=" as *u8); ri_puts(pm_mouth_why_name(res[PM_R_MOUTH_WHY])) 72 pmc_kv(" seam_px=" as *u8, res[PM_R_MOUTH_PIX]); pmc_kv(" seam_strength=" as *u8, res[PM_R_SEAM_STRENGTH]); pmc_kv(" seam_floor=" as *u8, res[PM_R_SEAM_FLOOR]); pmc_kv(" seam_hyp=" as *u8, res[PM_R_SEAM_HYP]); pmc_kv(" seam_probe_px=" as *u8, res[PM_R_SEAM_PROBE]); pmc_kv(" lip_reach_px=" as *u8, res[PM_R_LIP_REACH]); pmc_kv("," as *u8, res[PM_R_LIP_REACH_LO]) 73 pmc_kv(" mouth_box=" as *u8, res[PM_R_MX0]); pmc_kv("," as *u8, res[PM_R_MY0]); pmc_kv("," as *u8, res[PM_R_MX1]); pmc_kv("," as *u8, res[PM_R_MY1]) 74 pmc_kv(" stomion_y=" as *u8, res[PM_R_STOMION_Y]); pmc_kv(" upper_over_lower_lip_permil=" as *u8, res[PM_R_LIP]) 75 ri_puts("\n" as *u8) 76 // AT44: the mouth as five landmarks, published whether or not the mouth passed (what was found before what was refused) 77 ri_puts("PHOTOMARK mouth(image x,y)" as *u8) 78 pmc_kv(" labrale_superius=" as *u8, res[PM_R_LS_X]); pmc_kv("," as *u8, res[PM_R_LS_Y]) 79 pmc_kv(" stomion=" as *u8, res[PM_R_STO_X]); pmc_kv("," as *u8, res[PM_R_STO_Y]) 80 pmc_kv(" labrale_inferius=" as *u8, res[PM_R_LI_X]); pmc_kv("," as *u8, res[PM_R_LI_Y]) 81 pmc_kv(" cheilion_R=" as *u8, res[PM_R_CHR_X]); pmc_kv("," as *u8, res[PM_R_CHR_Y]) 82 pmc_kv(" cheilion_L=" as *u8, res[PM_R_CHL_X]); pmc_kv("," as *u8, res[PM_R_CHL_Y]) 83 ri_puts("\n" as *u8) 84 } 85 if res[PM_R_EYES] != 2 { if res[PM_R_PAIR_FAIL] != PM_PF_NONE { 86 // PUBLISH WHAT WAS FOUND BEFORE DECIDING WHAT COULD NOT BE. The four canthi exist before the pair check refuses them, and a 87 // refusal that prints only its code cannot say whether the pair missed by a hair or by a mile -- MEASURED 2026-09-18, a 88 // mirror-symmetric render passed the asymmetry check at 305 of 350 permil and a lower-face edit alone then tipped it over, 89 // which only these numbers could show 90 let frw: i64 = pm_dist(res[PM_R_RLAT_X], res[PM_R_RLAT_Y], res[PM_R_RMED_X], res[PM_R_RMED_Y]) 91 let flw: i64 = pm_dist(res[PM_R_LMED_X], res[PM_R_LMED_Y], res[PM_R_LLAT_X], res[PM_R_LLAT_Y]) 92 ri_puts("PHOTOMARK pair_refused_candidates(image x,y)" as *u8) 93 pmc_kv(" R_lateral=" as *u8, res[PM_R_RLAT_X]); pmc_kv("," as *u8, res[PM_R_RLAT_Y]) 94 pmc_kv(" R_medial=" as *u8, res[PM_R_RMED_X]); pmc_kv("," as *u8, res[PM_R_RMED_Y]) 95 pmc_kv(" L_medial=" as *u8, res[PM_R_LMED_X]); pmc_kv("," as *u8, res[PM_R_LMED_Y]) 96 pmc_kv(" L_lateral=" as *u8, res[PM_R_LLAT_X]); pmc_kv("," as *u8, res[PM_R_LLAT_Y]) 97 pmc_kv(" fissure_R_px=" as *u8, frw); pmc_kv(" fissure_L_px=" as *u8, flw) 98 pmc_kv(" asym_permil=" as *u8, pm_abs(frw - flw) * PM_PERMIL / pm_max(pm_max(frw, flw), 1)); pmc_kv(" asym_limit_permil=" as *u8, PM_FISSURE_ASYM_PERMIL) 99 pmc_kv(" eye_pixels_R=" as *u8, res[PM_R_EYE_PIX_R]); pmc_kv(" eye_pixels_L=" as *u8, res[PM_R_EYE_PIX_L]) 100 ri_puts("\n" as *u8) 101 } } 102 return 0 103} 104func pmc_load(rc: *i64, out: *i64) -> i64 { 105 let face_c: *HaarCascade = ff_load_face(rc) 106 let eye_c: *HaarCascade = ff_load_eye(rc) 107 out[0] = face_c as i64 108 out[1] = eye_c as i64 109 if (face_c as i64) == 0 { return 0 } 110 if (eye_c as i64) == 0 { return 0 } 111 return 1 112} 113func main(argc: i64, argv: **u8) -> i64 { 114 if argc < PMC_ARGC_MEASURE { return pmc_usage() } 115 let verb: *u8 = argv[1] 116 let rc: *i64 = sys_mmap(PMC_I64) as *i64 117 let cs: *i64 = sys_mmap(2 * PMC_I64) as *i64 118 let loaded: i64 = pmc_load(rc, cs) 119 let face_c: *HaarCascade = cs[0] as *HaarCascade 120 let eye_c: *HaarCascade = cs[1] as *HaarCascade 121 if ri_streq(verb, "referee" as *u8) == 1 { 122 var dir: *u8 = PM_DEFAULT_DIR 123 if argc >= PMC_ARGC_REFEREE_DIR { dir = argv[3] } 124 pmc_kv("REFEREE cascades_loaded=" as *u8, loaded); ri_puts("\n" as *u8) 125 let judged: i64 = pm_referee(argv[2], dir, face_c, eye_c) 126 if judged == PM_E_READ { ri_puts("REFEREE oracle file unreadable\n" as *u8); return PMC_EXIT_READ } 127 return 0 128 } 129 let res: *i64 = sys_mmap(PM_R_N * PMC_I64) as *i64 130 if ri_streq(verb, "measure" as *u8) == 1 { 131 let r: i64 = pm_landmarks_file_auto(argv[2], res, face_c, eye_c) 132 if r == PM_E_READ { ri_puts("PHOTOMARK unreadable\n" as *u8); return PMC_EXIT_READ } 133 if r == PM_E_DECODE { ri_puts("PHOTOMARK decode failed\n" as *u8); return PMC_EXIT_DECODE } 134 pmc_kv("PHOTOMARK cascades_loaded=" as *u8, loaded); ri_puts("\n" as *u8) 135 pmc_report(argv[2], res) 136 if r == PM_E_NOFACE { ri_puts("PHOTOMARK verdict=UNMEASURED no face\n" as *u8); return PMC_EXIT_UNMEASURED } 137 if r == PM_E_NOEYES { ri_puts("PHOTOMARK verdict=UNMEASURED no eye pair passed the pair check\n" as *u8); return PMC_EXIT_UNMEASURED } 138 ri_puts("PHOTOMARK verdict=MEASURED\n" as *u8) 139 return 0 140 } 141 if ri_streq(verb, "card" as *u8) == 1 { 142 if argc < PMC_ARGC_CARD { return pmc_usage() } 143 let r: i64 = pm_landmarks_file_auto(argv[4], res, face_c, eye_c) 144 if r == PM_E_READ { ri_puts("PHOTOMARK unreadable\n" as *u8); return PMC_EXIT_READ } 145 if r == PM_E_DECODE { ri_puts("PHOTOMARK decode failed\n" as *u8); return PMC_EXIT_DECODE } 146 pmc_report(argv[4], res) 147 if r != PM_OK { ri_puts("PHOTOMARK verdict=UNMEASURED nothing written\n" as *u8); return PMC_EXIT_UNMEASURED } 148 let n: i64 = pm_card_write(argv[2], argv[3], argv[5], res) 149 if n == PM_E_EXISTS { ri_puts("PHOTOMARK card rows exist -- refused\n" as *u8); return PMC_EXIT_EXISTS } 150 if n == PM_E_READ { ri_puts("PHOTOMARK card unreadable\n" as *u8); return PMC_EXIT_READ } 151 pmc_kv("PHOTOMARK card rows_appended=" as *u8, n); ri_puts(" verdict=MEASURED\n" as *u8) 152 return 0 153 } 154 return pmc_usage() 155}