Optimization of Spectral Emission from Tunable LEDs for Hyperspectral Color Control via Particle Swarm Optimization
A Python framework for optimizing LED illumination configurations using particle swarm optimization (PSO) to maximize or minimize various color metrics (contrast, RGB difference, CIELAB delta E) from hyperspectral image data.
Optimizing spectral illumination to enhance feature visibility and contrast or conversely, to simulate color vision deficiencies is crucial for various applications in color science and vision research. This project addresses this challenge by designing an optimal illuminant using a 10-channel spectrally tunable LED light source controlled via Particle Swarm Optimization (PSO).
Given a hyperspectral image of an Ishihara test plate and spectral emission profiles of 10 tunable LEDs, this framework finds the optimal LED weight configuration (relative intensity combination) that either maximizes or minimizes color difference metrics:
- Michelson Contrast: Perceived contrast between two samples
- RGB Euclidean Distance (ΔRGB): Difference in red-green-blue channels
- CIELAB Color Difference (ΔE): Perceptually uniform color difference
- Hyperspectral Image: Captured via Specim V10E camera from an Ishihara test plate
- LED Emission Spectra: Measured with Hamamatsu PMA-12 spectrometer for 10 spectral channels
- User-Selected ROI: Interactive selection of two target color samples from the image
The PSO-optimized spectra demonstrate real-world efficacy:
- Minimization: The optimal spectrum designed to minimize color difference makes embedded test numbers difficult to recognize
- Maximization: The spectrum optimizing for maximum color difference makes test numbers clearly visible
- These results confirm PSO's effectiveness for controlling color appearance and contrast in targeted applications
Key Features:
- Interactive ROI selection from RGB composite visualization (430nm, 530nm, 630nm)
- Six optimization objectives (maximize/minimize contrast, RGB difference, ΔE)
- Modular color science utilities with proper D65 reference white handling
- Particle swarm optimization with proper out of gamut rejection
- Comprehensive spectral data processing and visualization
spectral-optimization-pso/
├── color_utils.py # Pure color science functions (731 lines)
│ ├── ENVI file I/O
│ ├── CIE 1931 color matching functions
│ ├── Spectral → XYZ → RGB/Lab conversions with D65 reference
│ └── LED spectrum utilities
│
├── maximize_contrast.py # Maximize Michelson contrast
├── minimize_contrast.py # Minimize Michelson contrast
├── maximize_rgb.py # Maximize RGB Euclidean distance
├── minimize_rgb.py # Minimize RGB Euclidean distance
├── maximize_deltaE.py # Maximize CIELAB ΔE
├── minimize_deltaE.py # Minimize CIELAB ΔE
│
├── LED.xlsx # LED spectral emission profiles
├── hyperspectral_sample/ # Sample hyperspectral data (ENVI format)
│ ├── sample_scan_0052.hdr # Header file with wavelengths
│ ├── sample_scan_0052.raw # Raw spectral data
│ ├── WHITEREF_sample_scan_0052.* # White reference
│ └── DARKREF_sample_scan_0052.* # Dark reference
│
└── results/ # Output directory (auto-created)
└── [objective]/ # Results for each optimization
├── 01_spectral_reflectance.png
├── 02_led_spectra.png
├── 03_optimal_illuminant.png
├── 04_comparison_optimal_vs_d65.png
└── optimal_illuminant_[objective]_[direction].txt
- Python 3.8+
- NumPy
- Pandas
- OpenCV (cv2)
- Colour-science
- Matplotlib
# Clone the repository
git clone https://github.com/kidat/spectral-optimization-pso.git
cd spectral-optimization-pso
# Add your hyperspectral sample under hyperspectral_sample folder
# Create virtual environment (recommended)
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install numpy pandas opencv-python colour-science matplotlib openpyxlRun any optimization program with interactive ROI selection:
# Maximize contrast
python maximize_contrast.py
# Minimize RGB difference
python minimize_rgb.py
# Maximize color difference (ΔE)
python maximize_deltaE.py- ROI Selection: Program displays RGB composite (430nm Blue, 530nm Green, 630nm Red)
- Click Selection: Click on 2 patches in the image window to select regions of interest
- Optimization: PSO automatically finds optimal LED weights
- Results: Generates 4 visualizations and optimal spectrum file
For each optimization run:
01_spectral_reflectance.png- Spectral curves of selected patches02_led_spectra.png- Individual LED spectra used03_optimal_illuminant.png- Optimal illuminant vs D6504_comparison_optimal_vs_d65.png- Side-by-side RGB/Lab comparisonoptimal_illuminant_[objective]_[direction].txt- Wavelength and emission intensity
- Color Spaces: CIE XYZ, sRGB (with gamma correction), CIELAB
- Reference White: D65 (95.047, 100.000, 108.883)
- Gamut Rejection: Out-of-gamut colors marked as NaN and excluded
- Color Metrics:
- Michelson contrast:
(Imax - Imin) / (Imax + Imin) - RGB distance: Euclidean distance in RGB space
- CIELAB ΔE: Euclidean distance in CIELAB space
- Michelson contrast:
Particle Swarm Optimization (PSO)
- Population: 100 particles
- Iterations: 50
- Constraint: LED weights sum to 1.0
- Velocity update with personal + global best tracking
- Out of gamut handling: Excludes invalid solutions from optimization
Each file follows the same structure:
- PSO algorithm (standalone implementation)
- Cost function specific to objective
- Data loading and preprocessing
- ROI selection with interactive RGB composite
- Optimization execution
- Result visualization and export
- Column 1: Wavelengths (nm)
- Columns 2-11: LED 1-10 intensity values
- All values normalized to max=1 internally
Lab = [L*, a*, b*]
L* = 116 * f(Y/Yn) - 16
a* = 500 * (f(X/Xn) - f(Y/Yn))
b* = 200 * (f(Y/Yn) - f(Z/Zn))
with reference white Xn=95.047, Yn=100.000, Zn=108.883 (D65)
- Color Science: Wyszecki & Stiles (2000), "Color Science: Concepts and Methods"
- CIE Standards: International Commission on Illumination (CIE)
- PSO: Kennedy & Eberhart (1995), "Particle Swarm Optimization"
- sRGB Gamma: IEC 61966-2-1:1999
Kidu A. Welegerima
MIT License - See LICENSE file for details
- Color Science Laboratory, University of Eastern Finland
Last Updated: December 14, 2025
Version: 1.0.0