lsst.pipe.tasks
g2c8cee2ce7+721f9a9580
Toggle main menu visibility
Loading...
Searching...
No Matches
python
lsst
pipe
tasks
prettyPictureMaker
_functors
_color_scale.py
Go to the documentation of this file.
1
# This file is part of pipe_tasks.
2
#
3
# Developed for the LSST Data Management System.
4
# This product includes software developed by the LSST Project
5
# (https://www.lsst.org).
6
# See the COPYRIGHT file at the top-level directory of this distribution
7
# for details of code ownership.
8
#
9
# This program is free software: you can redistribute it and/or modify
10
# it under the terms of the GNU General Public License as published by
11
# the Free Software Foundation, either version 3 of the License, or
12
# (at your option) any later version.
13
#
14
# This program is distributed in the hope that it will be useful,
15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
# GNU General Public License for more details.
18
#
19
# You should have received a copy of the GNU General Public License
20
# along with this program. If not, see <https://www.gnu.org/licenses/>.
21
22
from
__future__
import
annotations
23
24
__all__ = (
"ColorScaler"
,)
25
26
import
numpy
as
np
27
28
from
lsst.pipe.tasks.prettyPictureMaker.types
import
FloatImagePlane
29
from
lsst.pex.config.configurableActions
import
ConfigurableAction
30
from
lsst.pex.config
import
Field, ListField
31
32
from
.._equalizers
import
contrast_equalizer
33
34
35
class
ColorScaler
(ConfigurableAction):
36
saturation = Field[float](
37
doc=(
38
"The overall saturation factor with the scaled luminance between zero and one. "
39
"A value of one is not recommended as it makes bright pixels very saturated"
40
),
41
default=0.6,
42
)
43
maxChroma = Field[float](
44
doc=(
45
"The maximum chromaticity in the OKLCh color space, large "
46
"values will cause bright pixels to fall outside the RGB gamut."
47
),
48
default=0.4,
49
)
50
brightFalloff = Field[float](
51
doc=
"The rate that saturation scaling should slow with brightness"
, default=800, optional=
True
52
)
53
equalizer_levels = ListField[float](
54
doc=(
55
"A list of factors to modify the color constrast in a scale dependent way. "
56
"One coefficient for each spatial scale, starting from the largest. "
57
"Values large than 1 increase contrast, while less than 1 decreases"
58
"Only scales upto and including the largest to be modified need specified"
59
"IE [1.1,0.9] modifieds the first two [1.1,1,0.9] modifies the first three."
60
),
61
optional=
True
,
62
)
63
64
def
__call__
(
65
self, old_lum: FloatImagePlane, new_lum: FloatImagePlane, a: FloatImagePlane, b: FloatImagePlane
66
) -> tuple[FloatImagePlane, FloatImagePlane]:
67
"""
68
Adjusts the color saturation while keeping the hue constant.
69
70
This function adjusts the chromaticity (a, b) of colors to maintain a
71
consistent saturation level, based on their original luminance. It uses
72
the CIELAB color space representation and the `luminance` is the new target
73
luminance for all colors.
74
75
Parameters
76
----------
77
old_lum : `FloatImagePlane`
78
Luminance values of the original colors.
79
new_lum : `FloatImagePlane`
80
Target luminance values for the transformed colors.
81
a : `FloatImagePlane`
82
Chromaticity parameter 'a' corresponding to green-red axis in CIELAB.
83
b : `FloatImagePlane`
84
Chromaticity parameter 'b' corresponding to blue-yellow axis in CIELAB.
85
86
Returns
87
-------
88
new_a : `FloatImagePlane`
89
New a values representing the adjusted chromaticity.
90
new_b : `FloatImagePlane`
91
New b values representing the adjusted chromaticity.
92
"""
93
# Calculate the square of the chroma, which is the distance from origin in
94
# the a-b plane.
95
chroma1_2 = a**2 + b**2
96
chroma1 = np.sqrt(chroma1_2)
97
98
# Calculate the hue angle, taking the absolute value to ensure non-negative
99
# angle representation.
100
chromaMask = chroma1 == 0
101
chroma1[chromaMask] = 1
102
# Calculate sine and cosine of hue angle from chromaticity coordinates.
103
# In CIELAB a-b plane: sin(hue) = b/chroma, cos(hue) = a/chroma
104
# These are used below to preserve hue while adjusting chroma.
105
sinHue = b / chroma1
106
cosHue = a / chroma1
107
sinHue[chromaMask] = 0
108
cosHue[chromaMask] = 0
109
110
# Compute a divisor for saturation calculation, adding 1 to avoid division
111
# by zero.
112
div = chroma1_2 + old_lum**2
113
div[div <= 0] = 1
114
115
# Calculate the square of the new chroma based on desired saturation
116
sat_original_2 = chroma1_2 / div
117
if
self.
brightFalloff
is
None
:
118
chroma2_2 = self.
saturation
* sat_original_2 * new_lum**2 / (1 - sat_original_2)
119
else
:
120
correction_factor = np.arcsinh(abs(new_lum - 1) * self.
brightFalloff
) / np.arcsinh(
121
self.
brightFalloff
122
)
123
chroma2_2 = (
124
self.
saturation
125
* correction_factor**2
126
* sat_original_2
127
* new_lum**2
128
/ (1 - sat_original_2 * correction_factor**2)
129
)
130
131
# Compute new 'a' values using the square root of adjusted chroma and
132
# considering hue direction.
133
chroma2 = np.sqrt(chroma2_2)
134
if
self.
equalizer_levels
is
not
None
:
135
chroma2 = contrast_equalizer(chroma2, self.
equalizer_levels
)
136
# Cap the chroma to avoid excessive values that are visually unrealistic
137
chroma2[chroma2 > self.
maxChroma
] = self.
maxChroma
138
139
new_a = chroma2 * cosHue
140
141
# Compute new 'b' values using the root of the adjusted chroma and hue
142
# direction.
143
new_b = chroma2 * sinHue
144
145
return
new_a, new_b
lsst::pex::config::configurableActions
lsst.pipe.tasks.prettyPictureMaker._functors._color_scale.ColorScaler
Definition
_color_scale.py:35
lsst.pipe.tasks.prettyPictureMaker._functors._color_scale.ColorScaler.equalizer_levels
equalizer_levels
Definition
_color_scale.py:53
lsst.pipe.tasks.prettyPictureMaker._functors._color_scale.ColorScaler.brightFalloff
brightFalloff
Definition
_color_scale.py:50
lsst.pipe.tasks.prettyPictureMaker._functors._color_scale.ColorScaler.maxChroma
maxChroma
Definition
_color_scale.py:43
lsst.pipe.tasks.prettyPictureMaker._functors._color_scale.ColorScaler.__call__
tuple[FloatImagePlane, FloatImagePlane] __call__(self, FloatImagePlane old_lum, FloatImagePlane new_lum, FloatImagePlane a, FloatImagePlane b)
Definition
_color_scale.py:66
lsst.pipe.tasks.prettyPictureMaker._functors._color_scale.ColorScaler.saturation
saturation
Definition
_color_scale.py:36
lsst::pex::config
lsst.pipe.tasks.prettyPictureMaker.types
Definition
types.py:1
Generated on
for lsst.pipe.tasks by
1.17.0