D
Documentation
v1.0.0
Color Distance
Color distance (Delta E) is a metric for measuring the perceived difference between two colors. Colorium implements three industry-standard algorithms for color distance calculation.
Overview of Distance Methods
| Method | Description | Best For |
|---|---|---|
| CIE76 | Simple Euclidean distance in LAB space | Quick estimates |
| CIE94 | Improved with weighting factors | Graphic arts |
| CIEDE2000 | Industry standard with perceptual corrections | Accurate color matching |
Understanding Delta E
Delta E values indicate how different two colors appear:
| Delta E Range | Perceptual Difference |
|---|---|
| 0 - 1 | Imperceptible |
| 1 - 2 | Barely perceptible |
| 2 - 10 | Perceptible |
| 10 - 20 | Noticeable |
| 20 - 50 | Very different |
| 50+ | Completely different |
CIE76 Distance
The simplest Delta E method using Euclidean distance in LAB space.
1
2
3
4
5
6
7
8
from colorium import Color
color1 = Color(100, 150, 200)
color2 = Color(120, 130, 180)
# Calculate CIE76 distance
distance = color1.delta_e(color2, "cie76")
print(f"CIE76: {distance:.2f}")When to Use CIE76
- Quick estimates
- Simple color difference needs
- Legacy systems
- When accuracy is not critical
CIE94 Distance
Improves upon CIE76 with weighting factors.
1
2
3
4
5
6
7
8
from colorium import Color
color1 = Color(100, 150, 200)
color2 = Color(120, 130, 180)
# Calculate CIE94 distance
distance = color1.delta_e(color2, "cie94")
print(f"CIE94: {distance:.2f}")When to Use CIE94
- Graphic arts applications
- Textile color matching
- When CIE76 is insufficient
- When CIEDE2000 is too complex
CIEDE2000 Distance
The most accurate Delta E method, industry standard.
1
2
3
4
5
6
7
8
from colorium import Color
color1 = Color(100, 150, 200)
color2 = Color(120, 130, 180)
# Calculate CIEDE2000 distance
distance = color1.delta_e(color2, "cie2000")
print(f"CIE2000: {distance:.2f}")When to Use CIEDE2000
- Industry color matching
- Quality control
- Color science research
- When maximum accuracy is required
Comparing Methods
1
2
3
4
5
6
7
8
9
10
11
12
13
from colorium import Color
color1 = Color(255, 0, 0) # Red
color2 = Color(0, 0, 255) # Blue
# Compare all methods
cie76 = color1.delta_e(color2, "cie76")
cie94 = color1.delta_e(color2, "cie94")
cie2000 = color1.delta_e(color2, "cie2000")
print(f"CIE76: {cie76:.2f}")
print(f"CIE94: {cie94:.2f}")
print(f"CIE2000: {cie2000:.2f}")Practical Examples
Color Matching
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from colorium import Color
def find_closest_color(target, palette):
"""Find the closest color in a palette"""
closest = None
min_distance = float('inf')
for color in palette:
distance = target.delta_e(color, "cie2000")
if distance < min_distance:
min_distance = distance
closest = color
return closest, min_distance
# Sample palette
palette = [
Color(255, 0, 0), # Red
Color(0, 255, 0), # Green
Color(0, 0, 255), # Blue
Color(255, 255, 0), # Yellow
Color(255, 0, 255), # Magenta
Color(0, 255, 255) # Cyan
]
# Find closest color
target = Color(200, 50, 50)
closest, distance = find_closest_color(target, palette)
print(f"Target: {target.to_hex_string()}")
print(f"Closest: {closest.to_hex_string()}")
print(f"Distance: {distance:.2f}")Color Quality Control
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
from colorium import Color
class ColorQualityControl:
def __init__(self, tolerance=2.0):
self.tolerance = tolerance
self.results = []
def check_color(self, sample, reference):
"""Check if color matches reference within tolerance"""
distance = sample.delta_e(reference, "cie2000")
passed = distance <= self.tolerance
self.results.append({
'sample': sample,
'reference': reference,
'distance': distance,
'passed': passed
})
return passed
def get_summary(self):
"""Get quality control summary"""
total = len(self.results)
passed = sum(1 for r in self.results if r['passed'])
return {
'total': total,
'passed': passed,
'failed': total - passed,
'pass_rate': passed / total if total > 0 else 0
}
# Usage
qc = ColorQualityControl(tolerance=3.0)
reference = Color(255, 0, 0)
samples = [
Color(254, 0, 0),
Color(255, 5, 0),
Color(240, 0, 0),
Color(200, 50, 50)
]
for sample in samples:
passed = qc.check_color(sample, reference)
print(f"{sample.to_hex_string()} → {'✓' if passed else '✗'}")
summary = qc.get_summary()
print(f"\nPass rate: {summary['pass_rate']:.0%}")Color Difference Visualization
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
from colorium import Color
def visualize_color_difference(color1, color2):
"""Visualize the difference between two colors"""
distances = {
'CIE76': color1.delta_e(color2, "cie76"),
'CIE94': color1.delta_e(color2, "cie94"),
'CIE2000': color1.delta_e(color2, "cie2000")
}
# Determine perception level
d = distances['CIE2000']
if d < 1:
perception = "Imperceptible"
elif d < 2:
perception = "Barely perceptible"
elif d < 10:
perception = "Perceptible"
elif d < 20:
perception = "Noticeable"
elif d < 50:
perception = "Very different"
else:
perception = "Completely different"
print(f"Color 1: {color1.to_hex_string()}")
print(f"Color 2: {color2.to_hex_string()}")
print(f"Perception: {perception}")
print(f"Delta E (CIE2000): {distances['CIE2000']:.2f}")
print(f"CIE76: {distances['CIE76']:.2f}")
print(f"CIE94: {distances['CIE94']:.2f}")
# Example
red = Color(255, 0, 0)
orange = Color(255, 128, 0)
visualize_color_difference(red, orange)Distance Tolerance Guidelines
For Different Applications
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from colorium import Color
def get_tolerance(application):
"""Get recommended tolerance for different applications"""
tolerances = {
'paint_matching': 1.0,
'textile_matching': 2.0,
'print_quality': 3.0,
'display_calibration': 1.5,
'color_grading': 2.5,
'general_use': 5.0
}
return tolerances.get(application, 5.0)
# Example
tolerance = get_tolerance('paint_matching')
print(f"Recommended tolerance: {tolerance}")Tolerance Classes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from colorium import Color
class ColorTolerance:
TIGHT = 1.0
MEDIUM = 2.0
LOOSE = 5.0
VERY_LOOSE = 10.0
@staticmethod
def get_description(tolerance):
descriptions = {
1.0: "Tight (precise matching)",
2.0: "Medium (standard quality)",
5.0: "Loose (general use)",
10.0: "Very loose (approximate)"
}
return descriptions.get(tolerance, "Custom")
# Usage
color1 = Color(100, 150, 200)
color2 = Color(105, 145, 195)
distance = color1.delta_e(color2, "cie2000")
tolerance = ColorTolerance.MEDIUM
print(f"Distance: {distance:.2f}")
print(f"Tolerance: {ColorTolerance.get_description(tolerance)}")
print(f"Pass: {distance <= tolerance}")Advanced Topics
Color Difference in Different Spaces
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
from colorium import Color
def compare_in_spaces(color1, color2):
"""Compare colors in different spaces"""
# RGB difference
rgb_diff = (
abs(color1.red - color2.red) +
abs(color1.green - color2.green) +
abs(color1.blue - color2.blue)
) / 3
# HSL difference
hsl1 = color1.to_hsl()
hsl2 = color2.to_hsl()
hsl_diff = (
abs(hsl1['h'] - hsl2['h']) / 360 +
abs(hsl1['s'] - hsl2['s']) +
abs(hsl1['l'] - hsl2['l'])
) / 3 * 100
# CIE2000 difference
cie_diff = color1.delta_e(color2, "cie2000")
return {
'rgb': rgb_diff,
'hsl': hsl_diff,
'cie2000': cie_diff
}
# Example
red = Color(255, 0, 0)
pink = Color(255, 200, 200)
results = compare_in_spaces(red, pink)
print("Color differences:")
print(f"RGB: {results['rgb']:.2f}")
print(f"HSL: {results['hsl']:.2f}")
print(f"CIE2000: {results['cie2000']:.2f}")Batch Distance Calculation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from colorium import Color
def batch_distance(target, colors):
"""Calculate distance to multiple colors"""
return [
{
'color': color,
'distance': target.delta_e(color, "cie2000")
}
for color in colors
]
# Sort by distance
target = Color(100, 150, 200)
colors = [
Color(120, 130, 180),
Color(255, 0, 0),
Color(100, 150, 200),
Color(0, 255, 0)
]
distances = batch_distance(target, colors)
sorted_distances = sorted(distances, key=lambda x: x['distance'])
for item in sorted_distances:
print(f"{item['color'].to_hex_string()}: {item['distance']:.2f}")Best Practices
Choose the Right Method
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from colorium import Color
def get_distance(color1, color2, accuracy="medium"):
"""Get distance with appropriate accuracy"""
methods = {
'quick': 'cie76',
'medium': 'cie94',
'accurate': 'cie2000'
}
method = methods.get(accuracy, 'cie2000')
return color1.delta_e(color2, method)
# Usage
distance = get_distance(
Color(100, 150, 200),
Color(120, 130, 180),
accuracy="accurate"
)Cache Distance Results
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from colorium import Color
from functools import lru_cache
class ColorDistanceCache:
def __init__(self):
self.cache = {}
def get_distance(self, color1, color2, method="cie2000"):
# Create cache key
key = (
(color1.red, color1.green, color1.blue),
(color2.red, color2.green, color2.blue),
method
)
if key not in self.cache:
self.cache[key] = color1.delta_e(color2, method)
return self.cache[key]
# Usage
cache = ColorDistanceCache()
color1 = Color(100, 150, 200)
color2 = Color(120, 130, 180)
# First call calculates
distance1 = cache.get_distance(color1, color2)
# Second call uses cache
distance2 = cache.get_distance(color1, color2)Next Steps
- Color Similarity — Similarity scoring
- Named Colors — Using named colors
- Advanced Topics — Advanced color operations
Previous: Color Blending Next: Color Similarity →
On this page
23 sections