4 KiB
Feature Specification v1
Scope
Per-artwork feature extraction is deterministic and corpus-independent. Running the extractor for the same canonical inputs and extractor version must produce the same output regardless of how many other artworks exist.
Palette input
Prefer an explicit SMK weighted palette when valid. Preserve the source representation.
For colors_palette_weighted_s, the observed format may contain repeated space-separated hex tokens. Parse defensively:
- tokenize valid colours,
- count each colour,
- divide by total valid token count,
- retain an explicit
weight_source, - quality-flag malformed/partial input.
If weights are unavailable, do not label equal/fallback weights as original SMK weights. A fallback can be supported if explicitly identified.
Canonical weights must satisfy approximately:
weight >= 0
sum(weight) = 1
Colour conversion
Use:
sRGB -> linear RGB -> OKLab -> OKLCH
Use a single documented conversion implementation throughout v1 and test it against known reference colours.
Perceptual colour centroid
Calculate the weighted mean in OKLab:
L = Σ(wᵢLᵢ)
a = Σ(wᵢaᵢ)
b = Σ(wᵢbᵢ)
Store:
centroid_lcentroid_acentroid_bcentroid_chromacentroid_hue_degcentroid_hue_xcentroid_hue_y
Convert the centroid to OKLCH for chroma/hue. Hue is undefined for sufficiently achromatic centroids; use null rather than inventing a direction.
Palette statistics
dominant_color_weight
Largest normalized palette weight.
palette_entropy_01
Normalized Shannon entropy:
H = -Σ(pᵢ ln pᵢ)
H01 = H / ln(n)
For n <= 1, define palette_entropy_01 = 0.0.
effective_palette_size
exp(H)
using unnormalized natural-log entropy.
palette_spread
Weighted mean Euclidean OKLab distance from palette colours to the weighted centroid.
lightness_stddev
Weighted standard deviation of OKLab L.
chroma_stddev
Weighted standard deviation of OKLCH chroma.
hue_concentration_01
Magnitude of a chroma-aware circular resultant where each hue contribution is weighted by:
palette_weight * chroma
Return null when total chromatic mass is effectively zero.
SMK-provided visual features
Preserve independently from our own calculations when present:
smk_brightnesssmk_contrastsmk_saturationsmk_colortempsmk_entropy
SMK image entropy and our palette entropy are different concepts.
If multiple enrichment components/versions provide competing values, retain provenance and use an explicit precedence rule. Never silently mix components.
Geometry
Canonical geometry/features:
physical_width_cmphysical_height_cmphysical_depth_cmphysical_area_cm2physical_aspect_ratioimage_aspect_ratiolog_width_cmlog_height_cmlog_area_cm2
Rules:
- prefer meaningful Netto dimensions over Brutto when both are available,
- normalize supported units to centimetres,
- do not infer physical dimensions from pixel dimensions,
- calculate area/aspect only where width + height are meaningful,
- calculate logarithms only for positive valid values.
Aspect sanity check
For suitable 2D works where both physical and image aspect ratios exist, compare them using a symmetric log-ratio measure, e.g.:
abs(log(physical_aspect / image_aspect))
Flag large mismatches; do not automatically “correct” either source.
Quality/support fields
Include:
feature_schema_versionextractor_version- source snapshot references
- enrichment component/version provenance when available
quality_flags
Initial quality-flag vocabulary may include:
PALETTE_MISSINGPALETTE_WEIGHTS_MISSINGPALETTE_MALFORMEDVERY_LOW_CHROMADIMENSIONS_MISSINGPHYSICAL_IMAGE_ASPECT_MISMATCHNON_2D_OBJECTSOURCE_LANGUAGE_MISMATCH
Flags describe observations; they should not automatically exclude records unless a named downstream profile says so.