Documentation
¶
Index ¶
- Variables
- func AdaptXYZ(X, Y, Z float32, Ws, Wd WhitePoint, method AdaptationMethod) (float32, float32, float32, error)
- func AvailableIlluminants() []string
- func DeltaE76(lab1, lab2 LAB) float32
- func DeltaE94(lab1, lab2 LAB, applicationType string) float32
- func DeltaE2000(lab1, lab2 LAB) float32
- func FindWavelengthIndex(wavelengths vecTypes.Vector, targetWavelength float32) (int, bool)
- func Integrate(wavelengths vecTypes.Vector, values vecTypes.Vector) float32
- func IntegrationKernel(wavelengths vecTypes.Vector) vec.Vector
- func LABToRGB(L, a, b float32, illuminant WhitePoint, out255 bool) (float32, float32, float32)
- func LABToXYZ(L, a, b float32, illuminant WhitePoint) (float32, float32, float32)
- func Luminance(X, Y, Z float32) float32
- func RGBToLAB(r, g, b float32, illuminant WhitePoint) (float32, float32, float32)
- func RGBToXYZ(r, g, b float32) (float32, float32, float32)
- func XYZToLAB(X, Y, Z float32, illuminant WhitePoint) (float32, float32, float32)
- func XYZToRGB(X, Y, Z float32, out255 bool) (float32, float32, float32)
- type AdaptationMethod
- type CalibrationPoint
- type ColorScience
- func (cs *ColorScience) Calibrate(dst *SPD, measurement SPD, optWhitePoint ...WhitePoint) error
- func (cs *ColorScience) ComputeCRI(spd SPD) (float32, error)
- func (cs *ColorScience) ComputeColorTemperature(spd SPD) (cct float32, duv float32, err error)
- func (cs *ColorScience) ComputeLuminance(spdMatrix matTypes.Matrix) (float32, error)
- func (cs *ColorScience) ComputeXYZ(spdMatrix matTypes.Matrix) (XYZ, error)
- func (cs *ColorScience) WhitePoint() WhitePoint
- type DataLoader
- type FilterShapeModel
- type InMemoryDatabase
- func (db *InMemoryDatabase) Add(name string, spd SPD, metadata SpectrumMetadata) error
- func (db *InMemoryDatabase) Get(name string) (SpectrumEntry, error)
- func (db *InMemoryDatabase) List() []string
- func (db *InMemoryDatabase) Remove(name string) error
- func (db *InMemoryDatabase) SearchByPeaks(peaks []Peak, maxResults int) ([]MatchResult, error)
- func (db *InMemoryDatabase) SearchBySimilarity(query SPD, maxResults int) ([]MatchResult, error)
- type LAB
- type MatchResult
- type ObserverCMF
- func (cmf ObserverCMF) Len() int
- func (cmf ObserverCMF) Wavelengths() SPD
- func (cmf ObserverCMF) WavelengthsValues() vec.Vector
- func (cmf ObserverCMF) XBar() SPD
- func (cmf ObserverCMF) XBarValues() vec.Vector
- func (cmf ObserverCMF) YBar() SPD
- func (cmf ObserverCMF) YBarValues() vec.Vector
- func (cmf ObserverCMF) ZBar() SPD
- func (cmf ObserverCMF) ZBarValues() vec.Vector
- type ObserverType
- type Option
- type Peak
- type RGB
- type SPD
- func CalibrateSensorSensitivity(referenceSPD, sensorResponseSPD SPD) (SPD, error)
- func CalibrateSensorSensitivityWithDark(referenceSPD, sensorResponseSPD, darkSPD SPD) (SPD, error)
- func FilterSPDFromChannel(channel SensorChannel, wavelengths vecTypes.Vector) SPD
- func GaussianSPDFromChannel(channel SensorChannel, wavelengths vecTypes.Vector) SPD
- func LoadIlluminantSPD(illuminantName string) (SPD, error)
- func NewSPD(wavelengths, values vecTypes.Vector) SPD
- func ReconstructSPDFromChannels(channels []SensorChannel, targetWavelengths vecTypes.Vector, useDampedLS bool, ...) (SPD, error)
- func ReconstructSPDWithConstraints(sensorResponses []SensorResponse, targetWavelengths vecTypes.Vector, ...) (SPD, error)
- func (spd SPD) Calibrate(pairs ...float32) (SPD, error)
- func (spd SPD) DetectCalibrationPoints(referenceSPD SPD, minConfidence float32) []CalibrationPoint
- func (spd SPD) Interpolate(targetWavelengths vecTypes.Vector) SPD
- func (spd SPD) Len() int
- func (spd SPD) Peaks(threshold, minProminence float32) []Peak
- func (spd SPD) Reconstruct(sensorResponses []SensorResponse, useDampedLS bool, lambda float32) error
- func (spd SPD) ReconstructFromChannels(channels []SensorChannel, useDampedLS bool, lambda float32) error
- func (spd SPD) ReconstructWeighted(sensorResponses []SensorResponse, weights vecTypes.Vector, useDampedLS bool, ...) error
- func (spd SPD) Valleys(threshold, minProminence float32) []Valley
- func (spd SPD) Values() vec.Vector
- func (spd SPD) Wavelengths() vec.Vector
- type SensorChannel
- type SensorResponse
- type SpectrumDatabase
- type SpectrumEntry
- type SpectrumMetadata
- type Valley
- type WhitePoint
- type XYZ
Constants ¶
This section is empty.
Variables ¶
var ( // D50/10 degree observer WhitePointD50_10 = WhitePoint{96.72, 100.000, 81.43} // D55/10 degree observer WhitePointD55_10 = WhitePoint{95.682, 100.000, 92.149} // D65/10 degree observer (standard for sRGB) WhitePointD65_10 = WhitePoint{94.81, 100.000, 107.32} // D75/10 degree observer WhitePointD75_10 = WhitePoint{94.972, 100.000, 122.638} // D50/2 degree observer WhitePointD50_2 = WhitePoint{96.422, 100.000, 82.521} // D65/2 degree observer WhitePointD65_2 = WhitePoint{95.047, 100.000, 108.883} // D75/2 degree observer WhitePointD75_2 = WhitePoint{94.972, 100.000, 122.638} // Illuminant A WhitePointA = WhitePoint{109.850, 100.000, 35.585} // Illuminant B WhitePointB = WhitePoint{99.092, 100.000, 85.313} // Illuminant C WhitePointC = WhitePoint{98.074, 100.000, 118.232} // Illuminant E WhitePointE = WhitePoint{100.000, 100.000, 100.000} // F1 WhitePointF1 = WhitePoint{92.834, 100.000, 103.665} // F2 WhitePointF2 = WhitePoint{99.187, 100.000, 67.395} // F3 WhitePointF3 = WhitePoint{103.754, 100.000, 49.861} // F4 WhitePointF4 = WhitePoint{109.147, 100.000, 38.813} // F5 WhitePointF5 = WhitePoint{90.872, 100.000, 98.723} // F6 WhitePointF6 = WhitePoint{97.309, 100.000, 60.188} // F7 WhitePointF7 = WhitePoint{95.044, 100.000, 108.755} // F8 WhitePointF8 = WhitePoint{96.413, 100.000, 82.333} // F9 WhitePointF9 = WhitePoint{100.365, 100.000, 67.868} // F10 WhitePointF10 = WhitePoint{96.174, 100.000, 108.882} // F11 WhitePointF11 = WhitePoint{100.966, 100.000, 64.370} // F12 WhitePointF12 = WhitePoint{108.046, 100.000, 39.228} // Common white LEDs WhitePointLED_CW_6500K = WhitePoint{95.04, 100.0, 108.88} WhitePointLED_NW_4300K = WhitePoint{97.0, 100.0, 92.0} WhitePointLED_WW_3000K = WhitePoint{98.5, 100.0, 67.0} WhitePointLED_VWW_2200K = WhitePoint{103.0, 100.0, 50.0} )
Standard white point constants.
Functions ¶
func AdaptXYZ ¶
func AdaptXYZ(X, Y, Z float32, Ws, Wd WhitePoint, method AdaptationMethod) (float32, float32, float32, error)
AdaptXYZ adapts XYZ values from source white point Ws to destination white point Wd.
func AvailableIlluminants ¶
func AvailableIlluminants() []string
AvailableIlluminants returns a list of available illuminant names.
func DeltaE76 ¶
DeltaE76 calculates the CIE76 color difference (ΔE) between two LAB color values. Formula: ΔE = sqrt((L1-L2)² + (a1-a2)² + (b1-b2)²) Uses Vector3D.Distance() for efficient Euclidean distance calculation.
func DeltaE94 ¶
DeltaE94 calculates the CIE94 color difference (ΔE94) between two LAB color values. Reference: https://en.wikipedia.org/wiki/Color_difference#CIE94 ApplicationType: "graphic" or "textiles" (graphic: K_L=1, K1=0.045, K2=0.015; textiles: K_L=2, K1=0.048, K2=0.014)
func DeltaE2000 ¶
DeltaE2000 calculates the CIEDE2000 color difference (ΔE00) between two LAB color values. Reference: https://en.wikipedia.org/wiki/Color_difference#CIEDE2000
func FindWavelengthIndex ¶
FindWavelengthIndex finds the index in a calibrated SPD vector that corresponds to the given wavelength (or nearest wavelength). Returns the index and true if exact match, false if nearest match.
func Integrate ¶
Integrate computes the integral of f(λ) over the wavelength range using trapezoidal rule. This is equivalent to kernel · f(λ) where kernel = IntegrationKernel(wavelengths).
func IntegrationKernel ¶
IntegrationKernel computes the trapezoidal integration kernel for a given wavelength vector. The kernel can be used to compute ∫f(λ)·dλ ≈ kernel · f(λ) using dot product. Returns a vector where kernel[i] represents the weight for f(wavelengths[i]) in the integration.
func LABToXYZ ¶
func LABToXYZ(L, a, b float32, illuminant WhitePoint) (float32, float32, float32)
LABToXYZ converts CIE LAB to CIE XYZ color space.
func Luminance ¶
Luminance calculates luminance (cd/m²) from CIE XYZ tristimulus values. Luminance is given by the Y component of XYZ. For absolute luminance, Y should be in cd/m² (requires calibration). For relative luminance, Y is normalized (0-100).
Parameters:
- X, Y, Z: CIE XYZ tristimulus values
Returns: luminance (Y component in cd/m² or normalized 0-100)
func RGBToLAB ¶
func RGBToLAB(r, g, b float32, illuminant WhitePoint) (float32, float32, float32)
RGBToLAB converts sRGB to CIE LAB by chaining RGBToXYZ → XYZToLAB.
Types ¶
type AdaptationMethod ¶
type AdaptationMethod string
AdaptationMethod specifies the chromatic adaptation transform method.
const ( // AdaptationBradford uses the Bradford transform matrix. AdaptationBradford AdaptationMethod = "bradford" // AdaptationVonKries uses the Von Kries transform matrix. AdaptationVonKries AdaptationMethod = "von_kries" // AdaptationCAT02 uses the CAT02 transform matrix. AdaptationCAT02 AdaptationMethod = "cat02" )
type CalibrationPoint ¶
type CalibrationPoint struct {
Index int // Index in the SPD (0-based)
Wavelength float32 // Actual wavelength in nanometers
}
CalibrationPoint represents a calibration point: index -> wavelength.
func DetectCalibrationPoints
deprecated
func DetectCalibrationPoints(measuredSPD, referenceSPD SPD, minConfidence float32) []CalibrationPoint
DetectCalibrationPoints is a convenience wrapper for the SPD method. Matches a measured SPD to a reference SPD and returns calibration points.
Deprecated: Use spd.DetectCalibrationPoints(referenceSPD, minConfidence) instead.
type ColorScience ¶
type ColorScience struct {
// contains filtered or unexported fields
}
ColorScience provides comprehensive spectral color calculations.
func New ¶
func New(opts ...Option) (*ColorScience, error)
New creates a new ColorScience instance with options. Defaults: D65 illuminant, 10-degree observer, WhitePointD65_10.
func (*ColorScience) Calibrate ¶
func (cs *ColorScience) Calibrate(dst *SPD, measurement SPD, optWhitePoint ...WhitePoint) error
Calibrate calibrates a measurement SPD according to dark and light calibration readings. Normalizes SPD readings to the light SPD given non-ideal illuminant and dark current.
The calibration process:
- Subtracts dark current from measurement and light: corrected = raw - dark
- Normalizes by light reading: calibrated = corrected_measurement / corrected_light
The output is normalized to the light SPD (reflectance or transmittance [0,1] relative to the reference light).
If optWhitePoint is provided and non-zero, it's used for reflective calibration normalization. The white point's Y value is used to scale reflectance to 100% for the reference white.
Parameters:
- dst: Output SPD (must already be initialized with wavelengths)
- measurement: Raw measurement SPD
- optWhitePoint: Optional white point for reflective calibration (if not provided, uses configured white point)
Returns error if dark or light calibration SPDs are not set, or if wavelengths don't match.
func (*ColorScience) ComputeCRI ¶
func (cs *ColorScience) ComputeCRI(spd SPD) (float32, error)
ComputeCRI computes the Color Rendering Index (CRI) of an SPD as a light source. Returns the general CRI (Ra, average of 8 test color samples). CRI ranges from 0 to 100, with higher values indicating better color rendering.
The calculation compares the color rendering of test color samples under the test SPD versus under a reference illuminant with the same CCT.
Parameters:
- spd: SPD to compute CRI for (as a light source)
Returns: CRI Ra (0-100), error
func (*ColorScience) ComputeColorTemperature ¶
func (cs *ColorScience) ComputeColorTemperature(spd SPD) (cct float32, duv float32, err error)
ComputeColorTemperature computes the Correlated Color Temperature (CCT) and tint (duv) from an SPD. Returns CCT in Kelvin and duv (deviation from Planckian locus). Negative CCT indicates the chromaticity is outside the valid range.
Algorithm: Uses McCamy's formula for CCT and calculates duv as distance from Planckian locus.
func (*ColorScience) ComputeLuminance ¶
func (cs *ColorScience) ComputeLuminance(spdMatrix matTypes.Matrix) (float32, error)
ComputeLuminance computes luminance from a spectral power distribution matrix. Uses the configured CMF and illuminant from ColorScience. Returns absolute or relative luminance depending on the SPD units.
Parameters:
- cs: ColorScience instance with configured CMF and illuminant
- spdMatrix: Spectral power distribution matrix (1 row: values only, or 2 rows: wavelengths + values)
Returns: luminance (Y component), error
func (*ColorScience) ComputeXYZ ¶
func (cs *ColorScience) ComputeXYZ(spdMatrix matTypes.Matrix) (XYZ, error)
ComputeXYZ computes CIE XYZ tristimulus values from a spectral power distribution matrix. The input matrix can be:
- 1 row: values only (wavelengths match CMF/illuminant, no interpolation needed)
- 2 rows: row 0 = wavelengths, row 1 = values (interpolation to CMF/illuminant wavelengths)
func (*ColorScience) WhitePoint ¶
func (cs *ColorScience) WhitePoint() WhitePoint
WhitePoint returns the configured white point.
type DataLoader ¶
type DataLoader struct {
// contains filtered or unexported fields
}
DataLoader loads and manages CIE observer and illuminant spectral datasets.
func NewDataLoader ¶
func NewDataLoader() (*DataLoader, error)
NewDataLoader creates a new DataLoader and loads embedded SPD data.
func (*DataLoader) AvailableIlluminants ¶
func (dl *DataLoader) AvailableIlluminants() []string
AvailableIlluminants returns a list of available illuminant names.
func (*DataLoader) GetIlluminant ¶
func (dl *DataLoader) GetIlluminant(illuminant string) (SPD, error)
GetIlluminant returns the SPD for the specified illuminant. Returns full SPD data (no interpolation - illuminant has higher resolution than measured SPD).
func (*DataLoader) GetObserver ¶
func (dl *DataLoader) GetObserver(observer ObserverType) (ObserverCMF, error)
GetObserver returns the Color Matching Functions for the specified observer type. Returns full CMF data (no interpolation - CMF has higher resolution than measured SPD).
type FilterShapeModel ¶
type FilterShapeModel int
FilterShapeModel defines the filter shape model type.
const ( FilterShapeGaussian FilterShapeModel = 0 // Standard Gaussian (good general approximation) FilterShapeSuperGaussian4 FilterShapeModel = 1 // Super-Gaussian n=4 (steeper sides, better for interference filters) FilterShapeSuperGaussian6 FilterShapeModel = 2 // Super-Gaussian n=6 (very steep sides) FilterShapeBoxcar FilterShapeModel = 3 // Boxcar (flat top, sharp sides, ideal filter) )
type InMemoryDatabase ¶
type InMemoryDatabase struct {
// contains filtered or unexported fields
}
InMemoryDatabase is an in-memory implementation of SpectrumDatabase.
func (*InMemoryDatabase) Add ¶
func (db *InMemoryDatabase) Add(name string, spd SPD, metadata SpectrumMetadata) error
Add adds a spectrum to the database.
func (*InMemoryDatabase) Get ¶
func (db *InMemoryDatabase) Get(name string) (SpectrumEntry, error)
Get retrieves a spectrum by name.
func (*InMemoryDatabase) List ¶
func (db *InMemoryDatabase) List() []string
List returns all spectrum names in the database.
func (*InMemoryDatabase) Remove ¶
func (db *InMemoryDatabase) Remove(name string) error
Remove removes a spectrum from the database.
func (*InMemoryDatabase) SearchByPeaks ¶
func (db *InMemoryDatabase) SearchByPeaks(peaks []Peak, maxResults int) ([]MatchResult, error)
SearchByPeaks searches for spectra with similar peak patterns.
func (*InMemoryDatabase) SearchBySimilarity ¶
func (db *InMemoryDatabase) SearchBySimilarity(query SPD, maxResults int) ([]MatchResult, error)
SearchBySimilarity searches for spectra similar to the given SPD using correlation.
type LAB ¶
LAB represents CIE LAB color values.
func (LAB) ToRGB ¶
func (lab LAB) ToRGB(illuminant WhitePoint, out255 bool) RGB
ToRGB converts LAB to RGB using the provided white point. out255: if true, return values 0-255; if false, return 0-1.
func (LAB) ToXYZ ¶
func (lab LAB) ToXYZ(illuminant WhitePoint) XYZ
ToXYZ converts LAB to XYZ using the provided white point.
type MatchResult ¶
type MatchResult struct {
Entry SpectrumEntry // The matched spectrum entry
Score float32 // Similarity score (0-1, higher is better)
Confidence float32 // Confidence in the match (0-1)
}
MatchResult represents a match result from database search.
type ObserverCMF ¶
ObserverCMF contains Color Matching Functions as a 4-row matrix. Row 0: wavelengths Row 1: XBar Row 2: YBar Row 3: ZBar ObserverCMF embeds matTypes.Matrix interface, allowing methods to be attached while implementing the interface.
func LoadCMF ¶
func LoadCMF(observer ObserverType) (ObserverCMF, error)
LoadCMF loads Color Matching Functions for the specified observer. Returns full CMF data (CMF has higher resolution than measured SPD).
func (ObserverCMF) Len ¶
func (cmf ObserverCMF) Len() int
Len returns the number of wavelength/CMF pairs in a CMF.
func (ObserverCMF) Wavelengths ¶
func (cmf ObserverCMF) Wavelengths() SPD
Wavelengths returns the wavelengths as an SPD (row 0 + row 0).
func (ObserverCMF) WavelengthsValues ¶
func (cmf ObserverCMF) WavelengthsValues() vec.Vector
WavelengthsValues returns the wavelength vector (row 0) from a CMF.
func (ObserverCMF) XBar ¶
func (cmf ObserverCMF) XBar() SPD
XBar returns the XBar as an SPD (wavelengths row + XBar row 1).
func (ObserverCMF) XBarValues ¶
func (cmf ObserverCMF) XBarValues() vec.Vector
XBarValues returns the XBar vector (row 1) from a CMF.
func (ObserverCMF) YBar ¶
func (cmf ObserverCMF) YBar() SPD
YBar returns the YBar as an SPD (wavelengths row + YBar row 2).
func (ObserverCMF) YBarValues ¶
func (cmf ObserverCMF) YBarValues() vec.Vector
YBarValues returns the YBar vector (row 2) from a CMF.
func (ObserverCMF) ZBar ¶
func (cmf ObserverCMF) ZBar() SPD
ZBar returns the ZBar as an SPD (wavelengths row + ZBar row 3).
func (ObserverCMF) ZBarValues ¶
func (cmf ObserverCMF) ZBarValues() vec.Vector
ZBarValues returns the ZBar vector (row 3) from a CMF.
type ObserverType ¶
type ObserverType string
ObserverType represents a standard observer type.
const ( Observer2Deg ObserverType = "2" // CIE 1931 2 Degree Standard Observer Observer10Deg ObserverType = "10" // CIE 1964 10 Degree Standard Observer )
type Option ¶
type Option func(*ColorScience) error
Option configures a ColorScience instance.
func WithDark ¶
WithDark sets the dark calibration SPD (sensor dark reading). This is used to subtract dark current from measurements.
func WithIlluminant ¶
WithIlluminant sets the illuminant by name (e.g., "D65", "D50", "A"). Default: "D65" Automatically sets appropriate white point based on illuminant name and observer.
func WithIlluminantSPD ¶
WithIlluminantSPD sets a custom illuminant SPD.
func WithLight ¶
WithLight sets the light calibration SPD (reference white/light reading). This is used to normalize measurements to the reference illuminant.
func WithObserver ¶
func WithObserver(observer ObserverType) Option
WithObserver sets the observer type (default: Observer10Deg).
func WithWhitePoint ¶
func WithWhitePoint(wp WhitePoint) Option
WithWhitePoint sets the white point (default: WhitePointD65_10). Overrides any white point that would be auto-set by WithIlluminant.
type Peak ¶
type Peak struct {
Index int // Index in the SPD
Wavelength float32 // Wavelength at the peak
Value float32 // Peak value (intensity)
Prominence float32 // Prominence of the peak (height above surrounding baseline)
}
Peak represents a detected peak in an SPD.
type RGB ¶
RGB represents sRGB color values.
func (RGB) ToLAB ¶
func (rgb RGB) ToLAB(illuminant WhitePoint) LAB
ToLAB converts RGB to LAB using the provided white point.
type SPD ¶
SPD represents a Spectral Power Distribution as a 2-row matrix. Row 0: wavelengths Row 1: values SPD embeds matTypes.Matrix interface, allowing methods to be attached while implementing the interface.
func CalibrateSensorSensitivity ¶
CalibrateSensorSensitivity calibrates sensor spectral sensitivity using known reference measurements. Given a reference SPD with known spectral power and sensor responses to that SPD, calculates the sensor's spectral sensitivity (responsivity) function.
The calibration process:
- Measures sensor response to known reference SPD (calibration lamp, standard illuminant)
- Calculates sensitivity = response / reference_SPD at each wavelength
- Returns calibrated sensitivity SPD (wavelengths, sensitivity values)
Parameters:
- referenceSPD: Known reference SPD (e.g., standard illuminant or calibration lamp)
- sensorResponseSPD: Measured sensor response to the reference SPD (must have same wavelengths)
Returns: calibrated sensitivity SPD (wavelengths, sensitivity values), error
Example:
- Reference: D65 illuminant with known spectral power
- Sensor response: measured values when exposed to D65
- Result: sensor sensitivity function (responsivity at each wavelength)
func CalibrateSensorSensitivityWithDark ¶
CalibrateSensorSensitivityWithDark calibrates sensor spectral sensitivity accounting for dark current. Similar to CalibrateSensorSensitivity but subtracts dark current from sensor response first.
The calibration process:
- Subtracts dark current: corrected_response = response - dark
- Calculates sensitivity = corrected_response / reference_SPD at each wavelength
- Returns calibrated sensitivity SPD
Parameters:
- referenceSPD: Known reference SPD (e.g., standard illuminant or calibration lamp)
- sensorResponseSPD: Measured sensor response to the reference SPD
- darkSPD: Dark current measurement (sensor response with no light)
Returns: calibrated sensitivity SPD, error
func FilterSPDFromChannel ¶
func FilterSPDFromChannel(channel SensorChannel, wavelengths vecTypes.Vector) SPD
FilterSPDFromChannel creates an SPD representing a spectral filter response from center wavelength and FWHM. Supports multiple filter shapes optimized for interference filters like those in AS734x sensors.
Filter shapes:
- Gaussian (default): Good general approximation, y = exp(-0.5 * ((λ - center) / sigma)^2)
- Super-Gaussian (n=4): Steeper sides, better matches interference filters
- Super-Gaussian (n=6): Very steep sides, closer to ideal filters
- Boxcar: Flat top with sharp sides (idealized)
For interference filters (AS734x), Super-Gaussian (n=4) is typically most accurate.
Parameters:
- channel: SensorChannel with center wavelength, FWHM, and optional shape/asymmetry
- wavelengths: Target wavelength vector to evaluate the filter at
Returns: SPD representing the filter spectral response
func GaussianSPDFromChannel ¶
func GaussianSPDFromChannel(channel SensorChannel, wavelengths vecTypes.Vector) SPD
GaussianSPDFromChannel is a convenience wrapper for FilterSPDFromChannel using Gaussian shape. Deprecated: Use FilterSPDFromChannel with FilterShapeGaussian instead for better control.
func LoadIlluminantSPD ¶
LoadIlluminantSPD loads the SPD for the specified illuminant. Returns full SPD data (illuminant has higher resolution than measured SPD).
func ReconstructSPDFromChannels ¶
func ReconstructSPDFromChannels( channels []SensorChannel, targetWavelengths vecTypes.Vector, useDampedLS bool, lambda float32, ) (SPD, error)
ReconstructSPDFromChannels reconstructs an SPD from sensor channels specified by center wavelength and FWHM. This is a convenience wrapper that creates a new SPD with the target wavelengths and zeroed values, then calls ReconstructFromChannels().
Filter shape recommendations:
- FilterShapeSuperGaussian4 (recommended for AS734x): Best accuracy for interference filters
- FilterShapeSuperGaussian6: For very steep-sided filters
- FilterShapeGaussian: Simple approximation (default, less accurate for interference filters)
Parameters:
- channels: Array of SensorChannel with center wavelength, FWHM, readings, and optional shape/uncertainty
- targetWavelengths: Wavelength vector for the reconstructed SPD
- useDampedLS: If true, use damped least squares (Tikhonov regularization) - recommended for stability
- lambda: Regularization parameter for damped least squares (typically 0.01-0.1, only used if useDampedLS=true)
Returns: Reconstructed SPD, error
Example for AS7341 (recommended - using Super-Gaussian n=4):
wavelengths := vec.NewFrom(350.0, 360.0, 370.0, ..., 1000.0)
channels := []colorscience.SensorChannel{
{Name: "F1", CenterWL: 415, FWHM: 20, Reading: 1000, FilterShape: int(colorscience.FilterShapeSuperGaussian4)},
{Name: "F2", CenterWL: 445, FWHM: 20, Reading: 1500, FilterShape: int(colorscience.FilterShapeSuperGaussian4)},
// ... more channels
}
spd, err := colorscience.ReconstructSPDFromChannels(channels, wavelengths, true, 0.01)
func ReconstructSPDWithConstraints ¶
func ReconstructSPDWithConstraints( sensorResponses []SensorResponse, targetWavelengths vecTypes.Vector, useDampedLS bool, lambda float32, smoothnessWeight float32, ) (SPD, error)
ReconstructSPDWithConstraints reconstructs SPD with additional constraints. This is a more advanced version that allows specifying constraints like: - Non-negativity (already enforced in SPD.Reconstruct) - Smoothness (can be added via regularization) - Known values at specific wavelengths
For now, this is a convenience wrapper that creates an SPD with the target wavelengths and zeroed values, then calls SPD.Reconstruct(). Future enhancements could add: - Smoothness regularization (second derivative penalty) - Known value constraints - Bounds on values
func (SPD) Calibrate ¶
Calibrate calibrates the SPD using known wavelength calibration points. Takes variadic float32 values that must be even in length, interpreted as (index, wavelength) pairs. The SPD must already be initialized with wavelengths and values rows.
Calibration process:
- Uses the calibration points to calculate wavelengths for all indices using linear interpolation
- Updates the wavelength row of the SPD with the calibrated wavelengths
- The values row remains unchanged (values stay at their indices, wavelengths are corrected)
Example: Calibrate(0, 400.0, 100, 700.0) calibrates so that index 0 = 400nm, index 100 = 700nm, and wavelengths for intermediate indices are linearly interpolated.
func (SPD) DetectCalibrationPoints ¶
func (spd SPD) DetectCalibrationPoints(referenceSPD SPD, minConfidence float32) []CalibrationPoint
DetectCalibrationPoints matches this SPD to a reference SPD and returns calibration points. Uses correlation-based matching to find corresponding features between the two spectra. Returns (index, wavelength) pairs that can be used with SPD.Calibrate().
The algorithm:
- Interpolates both SPDs to a common wavelength grid
- Uses sliding window correlation to find best matches
- Detects peaks in both spectra and matches them
- Returns calibration points with confidence scores >= minConfidence
Parameters:
- referenceSPD: The reference SPD with known wavelengths (e.g., D65 illuminant, any known spectrum)
- minConfidence: Minimum confidence score (0-1) for a match to be included
Returns: slice of calibration points sorted by index in this SPD
func (SPD) Interpolate ¶
Interpolate resamples the SPD to new wavelengths using linear interpolation. The SPD is interpolated to match the target wavelengths (CMF/illuminant have higher resolution).
func (SPD) Peaks ¶
Peaks detects local maxima (peaks) in the SPD. Peaks are detected where values are higher than their neighbors. Only peaks with prominence >= minProminence are returned. Threshold filters out peaks below a minimum value.
Parameters:
- threshold: Minimum peak value to consider (0 = no threshold)
- minProminence: Minimum prominence for a peak to be included (0 = no prominence filter)
Returns: slice of detected peaks, sorted by wavelength
func (SPD) Reconstruct ¶
func (spd SPD) Reconstruct(sensorResponses []SensorResponse, useDampedLS bool, lambda float32) error
Reconstruct reconstructs the SPD values from measurements of multiple photodetectors with known spectral responses. The SPD must already be initialized with wavelengths row and zeroed values row. This solves the inverse problem: given sensor responses R and sensor spectral sensitivities S, find the stimulus SPD X such that R = S · X.
The problem is formulated as a linear system: R = S · X where:
- R is a vector of sensor readings (length = num_sensors)
- S is a matrix of sensor responses (num_sensors × num_wavelengths)
- X is the unknown stimulus SPD values (length = num_wavelengths)
This is solved using pseudo-inverse: X = S^+ · R
Parameters:
- sensorResponses: Array of sensor responses with their measured readings
- useDampedLS: If true, use damped least squares (Tikhonov regularization)
- lambda: Regularization parameter for damped least squares (only used if useDampedLS=true)
Returns error if reconstruction fails.
func (SPD) ReconstructFromChannels ¶
func (spd SPD) ReconstructFromChannels(channels []SensorChannel, useDampedLS bool, lambda float32) error
ReconstructFromChannels reconstructs an SPD from sensor channels specified by center wavelength and FWHM. This is a convenience wrapper that: 1. Creates filter SPD responses from channel specifications (Gaussian, Super-Gaussian, or Boxcar) 2. Converts to SensorResponse objects 3. Calls SPD.Reconstruct() or SPD.ReconstructWeighted() based on whether uncertainties are provided
This is useful for sensors like AS734x chips that only provide center wavelength and bandwidth information.
Filter shape recommendations for AS734x:
- FilterShapeSuperGaussian4 (recommended): Best matches interference filter characteristics
- FilterShapeSuperGaussian6: For very steep-sided filters
- FilterShapeGaussian: Simple approximation (faster, less accurate)
- FilterShapeBoxcar: Idealized filter (sharp sides, flat top)
If channels have Uncertainty > 0, weighted least squares is used automatically.
Parameters:
- spd: SPD to reconstruct (must have wavelengths initialized, values will be filled)
- channels: Array of SensorChannel with center wavelength, FWHM, readings, and optional shape/uncertainty
- useDampedLS: If true, use damped least squares (Tikhonov regularization)
- lambda: Regularization parameter for damped least squares (only used if useDampedLS=true)
Returns error if reconstruction fails.
Example for AS7341 (recommended - using Super-Gaussian for accuracy):
channels := []colorscience.SensorChannel{
{Name: "F1", CenterWL: 415, FWHM: 20, Reading: 1000, FilterShape: int(colorscience.FilterShapeSuperGaussian4)},
{Name: "F2", CenterWL: 445, FWHM: 20, Reading: 1500, FilterShape: int(colorscience.FilterShapeSuperGaussian4)},
{Name: "F3", CenterWL: 480, FWHM: 20, Reading: 1200, FilterShape: int(colorscience.FilterShapeSuperGaussian4)},
// ... more channels
}
spd := colorscience.NewSPD(wavelengths, vec.New(len(wavelengths)))
err := spd.ReconstructFromChannels(channels, true, 0.01) // Use damped LS for stability
Example with confidence intervals (weighted reconstruction):
channels := []colorscience.SensorChannel{
{Name: "F1", CenterWL: 415, FWHM: 20, Reading: 1000, Uncertainty: 0.05, FilterShape: int(colorscience.FilterShapeSuperGaussian4)},
{Name: "F2", CenterWL: 445, FWHM: 20, Reading: 1500, Uncertainty: 0.03, FilterShape: int(colorscience.FilterShapeSuperGaussian4)},
// Uncertainty = confidence interval as fraction (0.05 = 5% uncertainty)
}
func (SPD) ReconstructWeighted ¶
func (spd SPD) ReconstructWeighted(sensorResponses []SensorResponse, weights vecTypes.Vector, useDampedLS bool, lambda float32) error
ReconstructWeighted reconstructs the SPD using weighted least squares, accounting for measurement uncertainty. Measurements with higher uncertainty (lower confidence) are given less weight in the reconstruction.
Weighted least squares: minimize ||W · (S · X - R)||² where W is a diagonal weight matrix with weights w_i = 1 / uncertainty_i²
The solution is: X = (S^T · W² · S)^(-1) · S^T · W² · R
Parameters:
- sensorResponses: Array of sensor responses with readings
- weights: Weight vector (one per sensor). Higher weight = more trust in measurement. Weights are normalized if needed.
- useDampedLS: If true, use weighted damped least squares (Tikhonov regularization)
- lambda: Regularization parameter for damped least squares (only used if useDampedLS=true)
Returns error if reconstruction fails.
Note: If weights is nil or all zeros, falls back to unweighted reconstruction.
func (SPD) Valleys ¶
Valleys detects local minima (valleys) in the SPD. Valleys are detected where values are lower than their neighbors. Only valleys with prominence >= minProminence are returned. Threshold filters out valleys above a maximum value.
Parameters:
- threshold: Maximum valley value to consider (0 = no threshold, use very large value for no filter)
- minProminence: Minimum prominence for a valley to be included (0 = no prominence filter)
Returns: slice of detected valleys, sorted by wavelength
func (SPD) Wavelengths ¶
Wavelengths returns the wavelength vector (row 0) from an SPD.
type SensorChannel ¶
type SensorChannel struct {
Name string // Channel name/identifier
CenterWL float32 // Center wavelength in nanometers
FWHM float32 // Full width at half maximum (FWHM) in nanometers
Reading float32 // Measured response value (optional, can be set later)
Uncertainty float32 // Measurement uncertainty/confidence (0 = no weight, >0 = 1/uncertainty² weight). If >0, used as weight in weighted least squares.
FilterShape int // Filter shape model: 0=Gaussian (default), 1=Super-Gaussian (n=4, steeper), 2=Super-Gaussian (n=6, very steep), 3=Boxcar (flat top, sharp sides)
Asymmetry float32 // Asymmetry factor (-1 to 1): 0=symmetric, >0=redshifted, <0=blueshifted. Default 0.
}
SensorChannel represents a sensor channel with center wavelength and full width at half maximum (FWHM). This is useful for sensors like AS734x chips that only provide center wavelength and bandwidth.
type SensorResponse ¶
type SensorResponse struct {
Name string // Sensor name/identifier
Response matTypes.Matrix // Spectral response of the sensor (wavelengths -> response) - must be 2-row SPD matrix
Reading float32 // Measured response value to the stimulus
}
SensorResponse represents a photodetector with its known spectral response.
func SensorChannelsToResponses ¶
func SensorChannelsToResponses(channels []SensorChannel, targetWavelengths vecTypes.Vector) []SensorResponse
SensorChannelsToResponses converts SensorChannel specifications with readings to SensorResponse objects. Each channel's filter response SPD (Gaussian, Super-Gaussian, or Boxcar) is evaluated at the target wavelengths.
Parameters:
- channels: Array of SensorChannel with center wavelength, FWHM, readings, and optional shape/uncertainty
- targetWavelengths: Wavelength vector to evaluate the filter responses at
Returns: Array of SensorResponse ready for use with SPD.Reconstruct() or SPD.ReconstructWeighted()
type SpectrumDatabase ¶
type SpectrumDatabase interface {
// Add adds a spectrum to the database.
Add(name string, spd SPD, metadata SpectrumMetadata) error
// SearchBySimilarity searches for spectra similar to the given SPD.
// Returns ranked matches sorted by similarity score (highest first).
SearchBySimilarity(query SPD, maxResults int) ([]MatchResult, error)
// SearchByPeaks searches for spectra with similar peak patterns.
// Returns ranked matches sorted by similarity score (highest first).
SearchByPeaks(peaks []Peak, maxResults int) ([]MatchResult, error)
// Get retrieves a spectrum by name.
Get(name string) (SpectrumEntry, error)
// List returns all spectrum names in the database.
List() []string
// Remove removes a spectrum from the database.
Remove(name string) error
}
SpectrumDatabase provides an interface for storing and searching spectra.
func NewSpectrumDatabase ¶
func NewSpectrumDatabase() SpectrumDatabase
NewSpectrumDatabase creates a new in-memory spectrum database.
type SpectrumEntry ¶
type SpectrumEntry struct {
SPD SPD // The spectrum SPD
Metadata SpectrumMetadata // Metadata about the spectrum
}
SpectrumEntry represents a spectrum entry in the database.
type SpectrumMetadata ¶
type SpectrumMetadata struct {
Name string // Spectrum name/identifier
Description string // Description of the spectrum
Type string // Spectrum type (reflectance, absorption, raman, emission, etc.)
Properties map[string]string // Additional properties (material, source, etc.)
}
SpectrumMetadata contains metadata for a spectrum in the database.
type Valley ¶
type Valley struct {
Index int // Index in the SPD
Wavelength float32 // Wavelength at the valley
Value float32 // Valley value (intensity)
Prominence float32 // Prominence of the valley (depth below surrounding baseline)
}
Valley represents a detected valley in an SPD.
type WhitePoint ¶
WhitePoint represents a CIE XYZ white point.
type XYZ ¶
XYZ represents CIE XYZ tristimulus values.
func (XYZ) Adapt ¶
func (xyz XYZ) Adapt(Ws, Wd WhitePoint, method AdaptationMethod) (XYZ, error)
Adapt adapts XYZ values from source white point to destination white point. Returns adapted XYZ using the specified adaptation method.
func (XYZ) ToLAB ¶
func (xyz XYZ) ToLAB(illuminant WhitePoint) LAB
ToLAB converts XYZ to LAB using the provided white point.