Dyeing & Colour Matching
Spectrophotometric Modelling, ΔE CIE2000 Optimisation, and Right-First-Time Rate Improvement
The Economics of a Wrong Shade
A batch redye in a Tirupur processing house adds ₹12–18/kg in chemical and energy cost, extends the lead time by 12–24 hours, degrades fibre strength by 4–8% per additional high-temperature cycle, and risks shade variation across the redyed lot when the original fibre batch is exhausted. For a 500 kg reactive dyeing lot, a single redye costs ₹6,000–9,000 plus the lead time hit. At 20–25% industry average redye rates, the annual loss across a mid-size processing house (5,000 kg/day capacity) exceeds ₹2.2 crore. Predictive recipe optimisation that pushes right-first-time (RFT) rate from 75% to 92% saves ₹1.2+ crore annually — before counting the sustainability benefits.
Open data/spectrophotometer-records.csv in the code panel. It contains 18 months of reflectance curves (400–700 nm at 10 nm intervals) from a Datacolor 650 spectrophotometer at a Surat dyeing house, linked to the recipe used (dye classes, concentrations, auxiliaries), lot parameters (fibre type, construction, weight), and process conditions (temperature profile, liquor ratio, pH at strike, salt concentration, wash-off sequence).
Spectrophotometric Data Foundations
CIE Colour Space and ΔE CIE2000
All colour matching work operates in CIELAB (L*, a*, b*) space rather than RGB or reflectance directly. The CIE2000 colour difference formula is mandatory for textile applications — ΔE76 and ΔE94 are obsolete for tolerancing:
import numpy as np
def delta_e_cie2000(lab1: tuple, lab2: tuple,
kL: float = 1.0, kC: float = 1.0, kH: float = 1.0) -> float:
"""
CIE2000 colour difference between lab1 and lab2 (L*, a*, b* tuples).
kL=2 for textiles (luminance weighted less heavily than chroma/hue).
"""
L1, a1, b1 = lab1
L2, a2, b2 = lab2
# Average L*
L_avg = (L1 + L2) / 2.0
# Chroma
C1 = np.sqrt(a1**2 + b1**2)
C2 = np.sqrt(a2**2 + b2**2)
C_avg = (C1 + C2) / 2.0
# a' adjustment
G = 0.5 * (1 - np.sqrt(C_avg**7 / (C_avg**7 + 25**7)))
a1p = a1 * (1 + G)
a2p = a2 * (1 + G)
C1p = np.sqrt(a1p**2 + b1**2)
C2p = np.sqrt(a2p**2 + b2**2)
C_avg_p = (C1p + C2p) / 2.0
# Hue angle
h1p = np.degrees(np.arctan2(b1, a1p)) % 360
h2p = np.degrees(np.arctan2(b2, a2p)) % 360
# Hue difference
dh = h2p - h1p
if abs(dh) > 180:
dh -= np.sign(dh) * 360
dH = 2 * np.sqrt(C1p * C2p) * np.sin(np.radians(dh / 2))
H_avg_p = (h1p + h2p) / 2 if abs(h1p - h2p) <= 180 else (h1p + h2p + 360) / 2
# Correction terms
T = (1 - 0.17 * np.cos(np.radians(H_avg_p - 30))
+ 0.24 * np.cos(np.radians(2 * H_avg_p))
+ 0.32 * np.cos(np.radians(3 * H_avg_p + 6))
- 0.20 * np.cos(np.radians(4 * H_avg_p - 63)))
S_L = 1 + 0.015 * (L_avg - 50)**2 / np.sqrt(20 + (L_avg - 50)**2)
S_C = 1 + 0.045 * C_avg_p
S_H = 1 + 0.015 * C_avg_p * T
R_C = 2 * np.sqrt(C_avg_p**7 / (C_avg_p**7 + 25**7))
d_theta = 30 * np.exp(-((H_avg_p - 275) / 25)**2)
R_T = -np.sin(np.radians(2 * d_theta)) * R_C
dL = L2 - L1
dC = C2p - C1p
return float(np.sqrt(
(dL / (kL * S_L))**2 +
(dC / (kC * S_C))**2 +
(dH / (kH * S_H))**2 +
R_T * (dC / (kC * S_C)) * (dH / (kH * S_H))
))Industry tolerance bands vary by product segment: ΔE CIE2000 ≤ 1.0 for premium fashion (Arvind Limited's branded fabrics), ≤ 1.5 for standard export, ≤ 2.0 for domestic market mass production.
Dye Recipe Optimisation Models
Reactive Dye Systems (Cotton)
Reactive dyeing is the dominant process for cotton in Tirupur and Coimbatore. The key variables are dye concentration (% o.w.f.), salt (NaCl or Na₂SO₄, g/L), soda ash (Na₂CO₃, g/L), temperature profile, and exhaustion time. These interact non-linearly: high salt improves exhaustion but inhibits fixation at elevated pH; temperature ramp rate affects levelness.
| Variable | Typical Range | Effect on ΔE | Optimisation Priority |
|---|---|---|---|
| Dye concentration (% o.w.f.) | 0.01–8.0% | Primary shade depth driver | Model non-linearly (Beer-Lambert breaks > 4%) |
| NaCl/Na₂SO₄ (g/L) | 20–80 | Exhaustion %, levelness | Reduce — sustainability + cost |
| Na₂CO₃ (g/L) | 5–20 | Fixation rate, pH | Critical for RFT; optimise with temperature |
| Temperature (°C) | 50–80 | Fixation, exhaustion balance | Depends on dye reactivity class (bifunctional vs. monochlorotriazine) |
| Liquor ratio (L:R) | 1:5–1:15 | Uniformity, water use | Reduce — ZDHC water target |
Machine Learning Recipe Prediction
The prediction task: given a target CIELAB value (from a customer standard), predict the optimal dye recipe (3-component blend concentrations + key auxiliaries) to achieve ΔE CIE2000 ≤ 1.0 in a single dip.
The inverse problem (CIELAB → recipe) is harder than the forward problem (recipe → predicted CIELAB). Standard approach:
Prompt: "I need to match a Pantone 18-1438 TCX (Burnt Sienna) on 100% combed cotton fabric,
200 GSM, using a 3-dye reactive system (Remazol Red RB, Remazol Yellow RGB, Remazol Black B).
My historical data shows that similar orange-red shades on this fibre type require approximately
1.8–2.4% RB, 0.6–1.0% RGB, and 0.1–0.3% Black at 60°C fixation, 50 g/L salt, L:R 1:8.
The target L*=40.2, a*=28.6, b*=18.1. Propose an initial recipe and outline a 3-step
iterative correction protocol to reach ΔE CIE2000 < 1.0 within 2 trials."Disperse and Vat Dye Systems
Disperse dyeing (polyester, polyamide — dominant in Surat) adds thermodynamic complexity: the dye partitions between the bath and fibre as a function of temperature, dye structure (low/medium/high energy), and carrier presence. Shade buildup is sigmoidal vs. temperature — small variations in HT (130°C) dyeing temperature produce proportionally large ΔE changes.
Vat dyeing (indigo for denim, sulphur for bottoms) at Ahmedabad and Bhilwara denim mills is an oxidation-reduction system where the redox potential of the bath (measured via ORP sensor, mV) is the critical real-time control variable. ORP drift during the pad-steam process is the primary cause of shade variation across a 60-metre fabric roll.
Open data/disperse-dye-trials.json for 400 trial records from a Surat polyester mill, including temperature profiles, dye exhaustion curves, and final ΔE outcomes.
Right-First-Time Rate: Measurement and Improvement
RFT rate is computed per dye class, per colour family, and per machine:
from collections import defaultdict
def compute_rft(records: list[dict]) -> dict:
"""
records: list of {dye_class, colour_family, machine_id, delta_e, had_correction}
Returns RFT % by dye_class × colour_family.
"""
counts = defaultdict(lambda: {"total": 0, "rft": 0})
for r in records:
key = (r["dye_class"], r["colour_family"])
counts[key]["total"] += 1
if not r["had_correction"] and r["delta_e"] <= 1.5:
counts[key]["rft"] += 1
return {
f"{k[0]}/{k[1]}": round(v["rft"] / v["total"] * 100, 1)
for k, v in counts.items() if v["total"] >= 10
}Typical interventions that move RFT from 75% to 90%+:
Water and Chemical Reduction
Welspun India and Arvind Limited both publish water intensity KPIs in their sustainability reports — the benchmark is < 60 L/kg of processed fabric for reactive dyeing. The BTRA (Bombay Textile Research Association) has published a reference protocol for inline conductivity and pH monitoring that reduces auxiliary chemical use by 15–20% through real-time dosing adjustment.
ZDHC MRSL (Manufacturing Restricted Substances List) compliance requires that dye auxiliaries (levelling agents, fixatives, softeners) are pre-approved. Maintaining a digital BOM (Bill of Materials) per batch that maps each chemical to its ZDHC status is table stakes for buyers like H&M, Zara (Inditex), and M&S.
Key Takeaways
This is chapter 3 of AI for Textile & Apparel.
Get the full hands-on course — free during early access. Build the complete system. Your projects become your portfolio.
View course details