168 lines
4 KiB
Markdown
168 lines
4 KiB
Markdown
# 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:
|
|
|
|
```text
|
|
weight >= 0
|
|
sum(weight) = 1
|
|
```
|
|
|
|
## Colour conversion
|
|
|
|
Use:
|
|
|
|
```text
|
|
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:
|
|
|
|
```text
|
|
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:
|
|
|
|
```text
|
|
H = -Σ(pᵢ ln pᵢ)
|
|
H01 = H / ln(n)
|
|
```
|
|
|
|
For `n <= 1`, define `palette_entropy_01 = 0.0`.
|
|
|
|
### `effective_palette_size`
|
|
|
|
```text
|
|
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:
|
|
|
|
```text
|
|
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.:
|
|
|
|
```text
|
|
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.
|