smk-playground/docs/FEATURE_SPEC_V1.md

4.6 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

Milestone 3 uses canonical SMK bulk colors and preserves source representation and order. The bulk snapshots have no documented weights, so v1 uses explicitly labelled uniform analytical weights (1/n) after deduplicating exact repeated hex values. Repetition is not interpreted as weight.

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.

Uniform v1 weights are palette_weighting = "uniform", never original SMK weights. Future enrichment weights must retain separate provenance.

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

Convert the centroid to OKLCH for chroma/hue. Hue is undefined for sufficiently achromatic centroids; use null rather than inventing a direction.

Palette statistics

There is no dominant_color_weight in v1 because uniform weights do not measure image dominance. The first source colour and preserved source order are available without claiming dominance.

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_oklab

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 feature geometry:

  • net_width_cm
  • net_height_cm
  • net_area_cm2
  • net_aspect_ratio
  • image_aspect_ratio
  • log_net_width_cm
  • log_net_height_cm
  • log_net_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.

Corpus-relative derivatives

Normalization is specified separately in NORMALIZATION_V1.md. Raw OKLab coordinates remain the perceptual source of truth; normalized a/b variants do not preserve OKLab Euclidean distance. Circular hue x/y are alternative interpretation fields and are not combined with a/b in the primary color family.