color_tools.image.dominance

Perceptual dominant-color analysis for images.

The algorithm identifies colors that contribute most strongly to an image’s visual identity rather than merely returning the most common RGB values.

Pipeline:

image

-> downsample -> RGB to CIELAB -> provisional k-means clustering -> CIEDE2000 perceptual cluster merging -> spatial analysis and OpenCV saliency detection -> diagnostic multiscale nearest-neighbor support -> perceptual dominance scoring -> CIEDE2000 diversity selection -> requested number of dominant colors

The provisional k-means stage is purely a computational reduction step. Perceptual similarity and final palette selection use CIEDE2000.

class color_tools.image.dominance.DominantColor(rgb, lab, population, dominance, global_salience, local_contrast, spatial_distribution, spatial_coherence, lightness_contrast, focal_importance)[source]

Bases: object

A perceptually dominant color discovered in an image.

Variables:
  • rgb – Representative sRGB color.

  • lab – Representative CIELAB color.

  • population – Fraction of analyzed image pixels belonging to this color cluster.

  • dominance – Final perceptual-dominance score.

  • global_salience – Perceptual distinctiveness from the image’s other major colors.

  • local_contrast – Average CIEDE2000 contrast against neighboring pixels.

  • spatial_distribution – How broadly the color appears across the image.

  • spatial_coherence – How strongly the color forms contiguous regions rather than scattered pixels.

  • lightness_contrast – Difference in lightness from the image’s population-weighted average lightness.

  • focal_importance – Population-independent visual attention associated with the cluster, based on mean saliency per cluster pixel and normalized against the strongest cluster.

Parameters:
rgb: tuple[int, int, int]
lab: tuple[float, float, float]
population: float
dominance: float
global_salience: float
local_contrast: float
spatial_distribution: float
spatial_coherence: float
lightness_contrast: float
focal_importance: float
property hex: str

Return the representative color as #RRGGBB.

class color_tools.image.dominance.DominantColorDiagnostic(rgb, lab, population, population_score, coarse_support, coarse_support_mean, coarse_support_ratio, coarse_scale_persistence, structural_support, structural_penalty, global_salience, local_contrast, spatial_coherence, lightness_contrast, chroma, chromatic_prominence, neutrality, neutral_penalty, focal_saliency_share, mean_saliency, normalized_mean_saliency, focal_importance, base_dominance, dominance, selected_rank, selection_score, nearest_selected_distance, diversity_multiplier)[source]

Bases: object

Compact diagnostics for one surviving perceptual cluster.

Parameters:
rgb: tuple[int, int, int]
lab: tuple[float, float, float]
population: float
population_score: float
coarse_support: tuple[float, ...]
coarse_support_mean: float
coarse_support_ratio: float
coarse_scale_persistence: float
structural_support: float
structural_penalty: float
global_salience: float
local_contrast: float
spatial_coherence: float
lightness_contrast: float
chroma: float
chromatic_prominence: float
neutrality: float
neutral_penalty: float
focal_saliency_share: float
mean_saliency: float
normalized_mean_saliency: float
focal_importance: float
base_dominance: float
dominance: float
selected_rank: int | None
selection_score: float | None
nearest_selected_distance: float | None
diversity_multiplier: float | None
property hex: str

Return the representative color as #RRGGBB.

class color_tools.image.dominance.DominanceAnalysis(colors, focal_center, focal_radius, neutral_pixel_fraction, neutral_cluster_fraction, population_weighted_mean_chroma, high_chroma_pixel_fraction, accent_chroma_separation, color_pop_strength, coarse_dimensions, saliency_map, diagnostics=())[source]

Bases: object

Complete perceptual-dominance analysis.

The diagnostics intentionally stay compact. They retain the image-level color-pop measurements, the candidate signals still used by the algorithm, and multiscale nearest-neighbor support used for the current experiment.

Parameters:
colors: tuple[DominantColor, ...]
focal_center: tuple[float, float]
focal_radius: float
neutral_pixel_fraction: float
neutral_cluster_fraction: float
population_weighted_mean_chroma: float
high_chroma_pixel_fraction: float
accent_chroma_separation: float
color_pop_strength: float
coarse_dimensions: tuple[int, ...]
saliency_map: ndarray[tuple[Any, ...], dtype[float64]]
diagnostics: tuple[DominantColorDiagnostic, ...] = ()
color_tools.image.dominance.dominant_colors_to_palette(colors, *, source='dominance', name_prefix='Dominant')[source]

Convert dominant-color results into palette-ready ColorRecord objects.

Parameters:
  • colors (list[DominantColor] | tuple[DominantColor, ...]) – Dominant colors returned by dominant_colors() or analyze_dominant_colors().colors.

  • source (str) – Source label recorded on each ColorRecord.

  • name_prefix (str) – Prefix used when generating color names such as “Dominant 1”.

Return type:

list[ColorRecord]

color_tools.image.dominance.analyze_dominant_colors(image, count=8, *, provisional_clusters=None, merge_threshold=5.0, focal_weight=0.25, center_bias=0.1, focal_saliency=0.8, diversity_distance=15.0, diversity_floor=0.35, max_dimension=256, coarse_dimensions=(32, 64, 96), alpha_threshold=16, grid_size=4, minimum_cell_coverage=0.02, kmeans_iterations=100, seed=42, saliency_backend='opencv_fine_grained')[source]

Analyze the perceptually dominant colors in an image.

Parameters:
  • image (Image | str | Path) – PIL Image or filesystem path.

  • count (int) – Number of final colors to return. This does not determine the number of internal perceptual clusters.

  • provisional_clusters (int | None) – Number of initial k-means clusters used for computational reduction. Defaults to max(count * 8, 48), capped at 128.

  • merge_threshold (float) – Maximum CIEDE2000 distance at which provisional clusters are considered perceptually similar enough to merge.

  • focal_weight (float) – Influence of visual saliency on final color dominance. 0 disables focal weighting.

  • center_bias (float) – Strength of the optional center prior used by the saliency model.

  • focal_saliency (float) – Fraction of accumulated saliency enclosed by focal_radius.

  • diversity_distance (float) – CIEDE2000 distance considered fully distinct during final palette selection.

  • diversity_floor (float) – Minimum score multiplier applied to a color that is perceptually redundant with an already-selected color.

  • max_dimension (int) – Maximum image dimension used during the normal analysis path.

  • coarse_dimensions (tuple[int, ...]) – Long-side dimensions used for diagnostic nearest-neighbor structural support. These coarse views do not affect scoring or selection.

  • alpha_threshold (int) – Pixels with lower alpha values are excluded.

  • grid_size (int) – Grid resolution used for spatial-distribution analysis.

  • minimum_cell_coverage (float) – Minimum cluster coverage required for a grid cell to count as spatially occupied.

  • kmeans_iterations (int) – Maximum iterations for provisional k-means clustering.

  • seed (int) – Deterministic random seed used by k-means.

  • saliency_backend (Literal['opencv_fine_grained', 'opencv_spectral']) – OpenCV static saliency detector used for focal weighting. Fine Grained is the default; Spectral Residual is also available.

Return type:

DominanceAnalysis

Returns:

DominanceAnalysis containing selected colors and focal information.

color_tools.image.dominance.format_dominance_diagnostics(analysis)[source]

Format compact candidate diagnostics as tab-separated text.

The report intentionally omits superseded shadow-selection instrumentation. It focuses on the current image-level classifier, active scoring signals, and diagnostic multiscale nearest-neighbor structural support.

Return type:

str

Parameters:

analysis (DominanceAnalysis)

color_tools.image.dominance.dominant_colors(image, count=8, *, provisional_clusters=None, merge_threshold=5.0, focal_weight=0.25, center_bias=0.1, focal_saliency=0.8, diversity_distance=15.0, diversity_floor=0.35, max_dimension=256, coarse_dimensions=(32, 64, 96), alpha_threshold=16, grid_size=4, minimum_cell_coverage=0.02, kmeans_iterations=100, seed=42, saliency_backend='opencv_fine_grained')[source]

Return perceptually dominant colors without the additional analysis data.

This is the convenience API intended for normal library consumers.

Return type:

tuple[DominantColor, ...]

Parameters:
  • image (Image | str | Path)

  • count (int)

  • provisional_clusters (int | None)

  • merge_threshold (float)

  • focal_weight (float)

  • center_bias (float)

  • focal_saliency (float)

  • diversity_distance (float)

  • diversity_floor (float)

  • max_dimension (int)

  • coarse_dimensions (tuple[int, ...])

  • alpha_threshold (int)

  • grid_size (int)

  • minimum_cell_coverage (float)

  • kmeans_iterations (int)

  • seed (int)

  • saliency_backend (Literal['opencv_fine_grained', 'opencv_spectral'])