# Feature extractors One script per family. All read `data/artwork_metadata.csv` + `data/images/`, write to `data/features/`, checkpoint regularly, and resume if re-run. | family | script | dims | what it measures | |--------------|---------------------------|-----:|------------------| | hand-crafted | `extract_handcrafted.py` | 380 | color (HSV joint + grey-world + per-channel histograms), light (brightness/contrast/darkness/edge density), symmetry, flatness (SLIC superpixel LAB uniformity), texture (FFT radial bands + 59-bin nri-uniform LBP), lines (Hough count/density, straight ratio, edge-angle histogram) | | CLIP | `extract_clip.py` | 512 + 27 | ViT-B/16 image embedding + zero-shot cosine scores against 27 hand-written religious-attribute prompts | | DINOv2 | `extract_dino.py` | 768 | self-supervised CLS token — visual style/appearance similarity | | faces | `extract_faces.py` | 39 | YuNet detections summarized: count, coverage, sizes, positions, tilt/frontality, arrangement, spatial histograms | | pose | `extract_pose.py` | 39 | YOLOv8-pose, **largest figure only**: torso-normalised 17-keypoint skeleton + figure area + detection-quality columns + person count | Notes: - Hand-crafted features use the corrected preprocessing pipeline: images are border-cropped, guardedly background-masked (see `preprocessing/`), and capped at 1024 px on the longest side so texture/edge features measure the artwork rather than the museum's scan resolution. - The pose vector stores quality indicators (`main_kpt_conf`, `main_torso_px`) because photo-trained detectors are unreliable on stylised bodies — filter on them before interpreting posture.