Expand description
§MunsellSpace 🎨
High-precision sRGB to Munsell color space conversion with 99.98% reference accuracy.
This library provides the most accurate open-source implementation for converting RGB colors to Munsell notation, validated against the complete 4,007-color reference dataset.
§Quick Start
use munsellspace::MunsellConverter;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let converter = MunsellConverter::new()?;
// Convert RGB to Munsell
let munsell = converter.srgb_to_munsell([255, 0, 0])?;
println!("Pure red: {}", munsell); // Output: 7.9R 5.2/20.5
Ok(())
}§Features
- 99.98% Accuracy: Validated against complete reference dataset (4,006/4,007 exact matches)
- High Performance: 4,000+ colors/second batch processing
- Scientific Precision: Reference data lookup with intelligent interpolation
- Thread Safety: Full support for concurrent usage with
Send + Syncimplementations - Semantic Color Names: 30 color name overlays from Centore (2020) research
- Comprehensive Testing: Full test suite with accuracy validation
§About Munsell Color Space
The Munsell color system describes colors using three perceptually uniform dimensions:
- Hue: Color family (R, YR, Y, GY, G, BG, B, PB, P, RP)
- Value: Lightness from 0 (black) to 10 (white)
- Chroma: Saturation from 0 (neutral) to 15+ (vivid)
Example: 5R 4.0/14.0 = medium red (5R) with medium lightness (4.0) and high saturation (14.0).
§Thread Safety
All public types in MunsellSpace are thread-safe and implement Send + Sync. You can
safely share converters across multiple threads using Arc<T>:
use munsellspace::{MunsellConverter, IsccNbsClassifier};
use std::sync::Arc;
use std::thread;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create shared instances
let converter = Arc::new(MunsellConverter::new()?);
let classifier = Arc::new(IsccNbsClassifier::new()?);
let mut handles = vec![];
// Spawn multiple threads for concurrent processing
for thread_id in 0..4 {
let converter_clone = Arc::clone(&converter);
let classifier_clone = Arc::clone(&classifier);
let handle = thread::spawn(move || {
// Each thread can safely use the converters concurrently
let munsell = converter_clone.srgb_to_munsell([255, 0, 0]).unwrap();
if let (Some(hue), Some(chroma)) = (&munsell.hue, munsell.chroma) {
if let Ok(Some(iscc_color)) = classifier_clone.classify_munsell(hue, munsell.value, chroma) {
println!("Thread {}: {} -> {:?}", thread_id, munsell, iscc_color);
}
}
});
handles.push(handle);
}
// Wait for all threads to complete
for handle in handles {
handle.join().unwrap();
}
Ok(())
}Internal caches use Arc<RwLock<T>> for safe concurrent access, allowing multiple
readers or exclusive writers without data races.
§Semantic Color Names (v1.2.0+)
MunsellSpace includes 30 semantic color name overlays derived from Paul Centore’s 2020 research paper “Beige, aqua, fuchsia, etc.: Definitions for some non-basic surface colour names” (JAIC, 25, 24-54). These overlays define convex polyhedra in Munsell space for each color name, allowing you to determine which color names apply to any given Munsell color.
use munsellspace::{MunsellSpec, semantic_overlay, matching_overlays, get_registry};
fn main() {
// Parse a Munsell color and find matching color names
let color = MunsellSpec::new(7.4, 6.2, 3.4); // Near aqua centroid
// Get the best-matching color name
if let Some(name) = semantic_overlay(&color) {
println!("Best match: {}", name); // "aqua"
}
// Get all matching color names (colors can match multiple names)
let matches = matching_overlays(&color);
println!("All matches: {:?}", matches);
// Access the complete registry for advanced use
let registry = get_registry();
println!("Registry has {} overlays", registry.len()); // 30
}Available color names (30 total):
- Non-basic (20): aqua, beige, coral, fuchsia, gold, lavender, lilac, magenta, mauve, navy, peach, rose, rust, sand, tan, taupe, teal, turquoise, violet, wine
- Basic (10): blue, brown, gray, green, orange, pink, purple, red, white, yellow
§Unified Color Naming API (v1.2.0+)
The ColorClassifier provides a unified interface for all color naming systems.
From any color input, get complete naming information with consistent modifiers
across ISCC-NBS standard, extended, and semantic names.
use munsellspace::{ColorClassifier, ColorModifier};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let classifier = ColorClassifier::new()?;
// Classify any color format
let desc = classifier.classify_srgb([180, 80, 60])?;
// Get descriptors from all naming systems
println!("Standard: {}", desc.standard_descriptor()); // "moderate reddish brown"
println!("Extended: {}", desc.extended_descriptor()); // "moderate rust"
if let Some(semantic) = desc.semantic_descriptor() {
println!("Semantic: {}", semantic); // "moderate rust"
}
// The same modifier applies across all systems
println!("Modifier: {:?}", desc.modifier); // Moderate
// Format any modifier + color combination
let formatted = ColorModifier::Vivid.format("coral");
println!("{}", formatted); // "vivid coral"
Ok(())
}§Flexible Color Characterization (v1.2.1+)
The new characterization API separates objective color facts from formatting preferences, giving you complete control over how colors are described.
use munsellspace::{ColorClassifier, ColorCharacterization, FormatOptions, BaseColorSet, OverlayMode};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let classifier = ColorClassifier::new()?;
// Get objective characterization
let char = classifier.characterize_srgb([0, 0, 128])?;
// Access raw data
println!("ISCC-NBS #{}: {}", char.iscc_nbs_number, char.iscc_base_color);
println!("Semantic matches: {:?}", char.semantic_matches);
// Format with different preferences
let standard = FormatOptions::new(BaseColorSet::Standard, OverlayMode::Ignore);
let with_overlay = FormatOptions::new(BaseColorSet::Extended, OverlayMode::Include);
println!("Standard: {}", char.describe(&standard)); // "dark blue"
println!("With overlay: {}", char.describe(&with_overlay)); // "dark navy"
// Preset options for common cases
println!("{}", char.describe(&FormatOptions::standard())); // "dark blue"
println!("{}", char.describe(&FormatOptions::extended())); // "dark blue"
println!("{}", char.describe(&FormatOptions::standard_with_overlays())); // "dark navy"
println!("{}", char.describe(&FormatOptions::extended_with_overlays())); // "dark navy"
Ok(())
}BaseColorSet: Controls which ISCC-NBS names to use
Standard: 29 official ISCC-NBS base names (“vivid yellow green”, “dark greenish blue”)Extended: Uses lime/teal/turquoise for compound names (“vivid lime”, “dark teal”)
OverlayMode: Controls semantic overlay behavior
Ignore: Always use ISCC-NBS base colorsInclude: Use nearest semantic overlay when available
Re-exports§
pub use converter::MunsellConverter;pub use types::MunsellColor;pub use types::RgbColor;pub use types::IsccNbsName;pub use types::IsccNbsPolygon;pub use types::MunsellPoint;pub use error::MunsellError;pub use error::Result;pub use illuminants::Illuminant;pub use illuminants::ChromaticAdaptation;pub use illuminants::ChromaticAdaptationMethod;pub use iscc::IsccNbsClassifier;pub use iscc::ColorMetadata;pub use mechanical_wedges::MechanicalWedgeSystem;pub use mathematical::MathematicalMunsellConverter;pub use mathematical::MunsellSpecification;pub use mathematical::CieXyY;pub use mathematical::Illuminant as MathematicalIlluminant;pub use mathematical::ChromaticAdaptation as MathematicalChromaticAdaptation;pub use reverse_conversion::ReverseConverter;pub use reverse_conversion::ColorFormats;pub use reverse_conversion::CieLab;pub use reverse_conversion::HslColor;pub use reverse_conversion::HsvColor;pub use reverse_conversion::munsell_to_hex_string;pub use unified_cache::UnifiedColorCache;pub use unified_cache::CachedColorResult;pub use semantic_overlay::MunsellSpec;pub use semantic_overlay::MunsellCartesian;pub use semantic_overlay::SemanticOverlay;pub use semantic_overlay::SemanticOverlayRegistry;pub use semantic_overlay::parse_hue_to_number;pub use semantic_overlay::hue_number_to_string;pub use semantic_overlay::parse_munsell_notation;pub use semantic_overlay::semantic_overlay;Deprecated pub use semantic_overlay::matching_overlays;Deprecated pub use semantic_overlay::matching_overlays_ranked;Deprecated pub use semantic_overlay::matches_overlay;Deprecated pub use semantic_overlay::closest_overlay;Deprecated pub use semantic_overlay_data::create_overlay_registry;pub use semantic_overlay_data::get_registry;pub use color_names::ColorClassifier;pub use color_names::ColorDescriptor;pub use color_names::ColorModifier;pub use color_names::known_color_names;pub use color_names::is_known_color;pub use color_names::color_name_count;pub use color_names::ColorCharacterization;pub use color_names::FormatOptions;pub use color_names::BaseColorSet;pub use color_names::OverlayMode;
Modules§
- color_
interpolation - Interpolation and extrapolation classes - exact 1:1 port from Python colour-science Line-by-line port with exact behavior matching
- color_
math_ utils - Utility and validation functions - exact 1:1 port from Python colour-science Line-by-line port with exact behavior matching
- color_
names - Unified color naming API for MunsellSpace
- color_
notation_ parser - String parsing and formatting functions - exact 1:1 port from Python colour-science Line-by-line port with exact behavior matching
- constants
- Mathematical constants and datasets for Munsell color space conversion
- conversion_
helpers - Helper functions needed for the Python port These are utility functions used by the main algorithm
- converter
- High-precision sRGB to Munsell color space converter.
- error
- Error types for MunsellSpace conversion operations.
- illuminants
- Standard illuminants and chromatic adaptation
- iscc
- ISCC-NBS Color Name System Implementation
- lab_
color_ space - Lab color space functions - exact 1:1 port from Python colour-science Line-by-line port with exact behavior matching
- mathematical
- Mathematical Munsell color space conversion implementation
- mechanical_
wedges - Mechanical Wedge System for Deterministic ISCC-NBS Color Classification
- munsell_
color_ science - Exact 1:1 port of Python colour-science munsell functions This module contains exact implementations matching Python’s behaviour
- munsell_
converter_ core - Python-compatible Munsell converter This module integrates the exact 1:1 Python ports for accurate conversion
- reverse_
conversion - Reverse conversion pipeline: Munsell → Lab → sRGB/hex/HSL/HSV
- semantic_
overlay - Semantic overlay functionality for non-basic color names.
- semantic_
overlay_ data - Semantic overlay registry using Centore polyhedron data.
- types
- Core types for Munsell color space representation.
- unified_
cache
Constants§
- VERSION
- Library version