smk-playground/docs/FEATURE_SPEC_V1.md

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:

  1. tokenize valid colours,
  2. count each colour,
  3. divide by total valid token count,
  4. retain an explicit weight_source,
  5. 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_l
  • centroid_a
  • centroid_b
  • centroid_chroma
  • centroid_hue_deg
  • centroid_hue_x
  • centroid_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_brightness
  • smk_contrast
  • smk_saturation
  • smk_colortemp
  • smk_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_cm
  • physical_height_cm
  • physical_depth_cm
  • physical_area_cm2
  • physical_aspect_ratio
  • image_aspect_ratio
  • log_width_cm
  • log_height_cm
  • log_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_version
  • extractor_version
  • source snapshot references
  • enrichment component/version provenance when available
  • quality_flags

Initial quality-flag vocabulary may include:

  • PALETTE_MISSING
  • PALETTE_WEIGHTS_MISSING
  • PALETTE_MALFORMED
  • VERY_LOW_CHROMA
  • DIMENSIONS_MISSING
  • PHYSICAL_IMAGE_ASPECT_MISMATCH
  • NON_2D_OBJECT
  • SOURCE_LANGUAGE_MISMATCH

Flags describe observations; they should not automatically exclude records unless a named downstream profile says so.