code wiki / (root) / nx_skin_texture.nx

nx_skin_texture.nx source

↩ module page · 102 lines · 3925 B

1// nx_skin_texture.nx -- skin-texture realism detector. 2// 3// Pre-segmented-set convention: caller computes nx_region_segment(rgb) 4// in main() and passes set in. Verdict is allocated inside compute() 5// and returned by pointer. Field comparisons on the returned verdict 6// MUST bind through a local first (let k = v.kind; if k != X), per 7// docs/NISHILANG_TYPED_PRIMITIVES_GAP.md Gap 3. 8 9// nx_safety_envelope: 10// intended_use: AUTO_APPLIED -- primitive-specific tuning queued 11// sil_target: SIL1 12// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail] 13// verdict: NOT_YET_EVALUATED 14 15import "nx_syscalls.nx" 16import "nx_image.nx" 17import "nx_features.nx" 18import "nx_texture.nx" 19import "nx_region.nx" 20 21const NX_ST_UNKNOWN: i64 = 0 22const NX_ST_NORMAL: i64 = 1 23const NX_ST_PLASTIC_SHEEN: i64 = 2 24const NX_ST_TOO_NOISY: i64 = 3 25 26const NX_ST_ENERGY_PLASTIC_Q10: i64 = 900 27const NX_ST_CONTRAST_PLASTIC_Q10: i64 = 50 28const NX_ST_CONTRAST_NOISY_Q10: i64 = 500 29const NX_ST_HOMOGENEITY_NOISY_Q10: i64 = 300 30 31struct SkinTextureVerdict { 32 kind: i64, 33 torso_present: i64, 34 torso_glcm_contrast_q10: i64, 35 torso_glcm_energy_q10: i64, 36 torso_glcm_homogeneity_q10: i64, 37 face_freckle_count: i64, 38 severity_q10: i64, 39 fidelity_q10: i64, 40} 41 42func nx_skin_crop_gray(src: *Image, x0: i64, y0: i64, x1: i64, y1: i64) -> *Image { 43 let w: i64 = x1 - x0 44 let h: i64 = y1 - y0 45 let dst: *Image = nx_image_alloc(w, h, 1) 46 var y: i64 = 0 47 while y < h { 48 var x: i64 = 0 49 while x < w { 50 nx_image_set(dst, x, y, 0, nx_image_get(src, x + x0, y + y0, 0)) 51 x = x + 1 52 } 53 y = y + 1 54 } 55 return dst 56} 57 58func nx_skin_texture_compute(rgb: *Image, set: *RegionSet) -> *SkinTextureVerdict { 59 let verdict: *SkinTextureVerdict = (sys_mmap(96)) as *SkinTextureVerdict 60 verdict.kind = NX_ST_UNKNOWN 61 verdict.torso_present = 0 62 verdict.torso_glcm_contrast_q10 = 0 63 verdict.torso_glcm_energy_q10 = 0 64 verdict.torso_glcm_homogeneity_q10 = 0 65 verdict.face_freckle_count = 0 66 verdict.severity_q10 = 0 67 verdict.fidelity_q10 = 0 68 69 let t_idx: i64 = nx_region_find_kind(set, NX_REGION_TORSO) 70 if t_idx < 0 { return verdict } 71 verdict.torso_present = 1 72 73 let t_min_x: i64 = nx_region_get_field(set, t_idx, NX_REGION_F_BBOX_MIN_X) 74 let t_min_y: i64 = nx_region_get_field(set, t_idx, NX_REGION_F_BBOX_MIN_Y) 75 let t_max_x: i64 = nx_region_get_field(set, t_idx, NX_REGION_F_BBOX_MAX_X) 76 let t_max_y: i64 = nx_region_get_field(set, t_idx, NX_REGION_F_BBOX_MAX_Y) 77 let gray: *Image = nx_image_to_grayscale(rgb) 78 let torso_gray: *Image = nx_skin_crop_gray(gray, t_min_x, t_min_y, t_max_x + 1, t_max_y + 1) 79 let glcm: *i64 = (sys_mmap(64 * 8 + 16)) as *i64 80 nx_texture_glcm(torso_gray, 1, 0, glcm) 81 verdict.torso_glcm_contrast_q10 = nx_texture_contrast(glcm) 82 verdict.torso_glcm_energy_q10 = nx_texture_energy(glcm) 83 verdict.torso_glcm_homogeneity_q10 = nx_texture_homogeneity(glcm) 84 85 var kind: i64 = NX_ST_NORMAL 86 var sev: i64 = 0 87 let energy: i64 = verdict.torso_glcm_energy_q10 88 let contrast: i64 = verdict.torso_glcm_contrast_q10 89 let homo: i64 = verdict.torso_glcm_homogeneity_q10 90 if energy >= NX_ST_ENERGY_PLASTIC_Q10 { 91 if contrast < NX_ST_CONTRAST_PLASTIC_Q10 { kind = NX_ST_PLASTIC_SHEEN; sev = 768 } 92 } 93 if kind == NX_ST_NORMAL { 94 if contrast > NX_ST_CONTRAST_NOISY_Q10 { 95 if homo < NX_ST_HOMOGENEITY_NOISY_Q10 { kind = NX_ST_TOO_NOISY; sev = 384 } 96 } 97 } 98 verdict.kind = kind 99 verdict.severity_q10 = sev 100 verdict.fidelity_q10 = nx_region_get_field(set, t_idx, NX_REGION_F_CONF_Q10) 101 return verdict 102}