src
convert.cpp
Go to the documentation of this file.
1
/*
2
* Software License Agreement (BSD License)
3
*
4
* Copyright (c) 2020, Locus Robotics
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
*
11
* * Redistributions of source code must retain the above copyright
12
* notice, this list of conditions and the following disclaimer.
13
* * Redistributions in binary form must reproduce the above
14
* copyright notice, this list of conditions and the following
15
* disclaimer in the documentation and/or other materials provided
16
* with the distribution.
17
* * Neither the name of the copyright holder nor the names of its
18
* contributors may be used to endorse or promote products derived
19
* from this software without specific prior written permission.
20
*
21
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
* POSSIBILITY OF SUCH DAMAGE.
33
*/
34
35
#include <
color_util/convert.h
>
36
37
namespace
color_util
38
{
39
40
inline
float
toFloat
(
unsigned
char
n)
41
{
42
return
static_cast<
float
>
(n) / 255.0;
43
}
44
45
color_util::ColorRGBA
toFloat
(
const
color_util::ColorRGBA24
& int_color)
46
{
47
color_util::ColorRGBA
float_color;
48
float_color.
r
=
toFloat
(int_color.
r
);
49
float_color.
g
=
toFloat
(int_color.
g
);
50
float_color.
b
=
toFloat
(int_color.
b
);
51
float_color.
a
=
toFloat
(int_color.
a
);
52
return
float_color;
53
}
54
55
color_util::ColorHSVA
toFloat
(
const
color_util::ColorHSVA24
& int_color)
56
{
57
color_util::ColorHSVA
float_color;
58
float_color.
h
=
toFloat
(int_color.
h
);
59
float_color.
s
=
toFloat
(int_color.
s
);
60
float_color.
v
=
toFloat
(int_color.
v
);
61
float_color.
a
=
toFloat
(int_color.
a
);
62
return
float_color;
63
}
64
65
inline
unsigned
char
toInt
(
float
n)
66
{
67
return
static_cast<
unsigned
char
>
(n * 255.0);
68
}
69
70
color_util::ColorRGBA24
toInt
(
const
color_util::ColorRGBA
& float_color)
71
{
72
color_util::ColorRGBA24
int_color;
73
int_color.
r
=
toInt
(float_color.
r
);
74
int_color.
g
=
toInt
(float_color.
g
);
75
int_color.
b
=
toInt
(float_color.
b
);
76
int_color.
a
=
toInt
(float_color.
a
);
77
return
int_color;
78
}
79
80
color_util::ColorHSVA24
toInt
(
const
color_util::ColorHSVA
& float_color)
81
{
82
color_util::ColorHSVA24
int_color;
83
int_color.
h
=
toInt
(float_color.
h
);
84
int_color.
s
=
toInt
(float_color.
s
);
85
int_color.
v
=
toInt
(float_color.
v
);
86
int_color.
a
=
toInt
(float_color.
a
);
87
return
int_color;
88
}
89
90
// Colorspace conversions based on
91
// https://stackoverflow.com/questions/3018313/algorithm-to-convert-rgb-to-hsv-and-hsv-to-rgb-in-range-0-255-for-both
92
color_util::ColorHSVA
changeColorspace
(
const
color_util::ColorRGBA
& rgba)
93
{
94
color_util::ColorHSVA
out;
95
96
// Alpha channel
97
out.
a
= rgba.
a
;
98
99
// Three way max/min
100
double
min = rgba.
r
< rgba.
g
? rgba.
r
: rgba.
g
;
101
min = min < rgba.
b
? min : rgba.
b
;
102
103
double
max = rgba.
r
> rgba.
g
? rgba.
r
: rgba.
g
;
104
max = max > rgba.
b
? max : rgba.
b
;
105
106
// Value Channel
107
out.
v
= max;
108
109
double
delta = max - min;
110
if
(max == 0.0 || delta < 0.00001)
111
{
112
// Grayscale
113
out.
s
= 0;
114
out.
h
= 0;
// undefined hue
115
return
out;
116
}
117
118
// Saturation Channel (note max!=0)
119
out.
s
= (delta / max);
120
121
if
(rgba.
r
>= max)
// > is invalid for valid input
122
{
123
out.
h
= (rgba.
g
- rgba.
b
) / delta;
// between yellow & magenta
124
}
125
else
if
(rgba.
g
>= max)
126
{
127
out.
h
= 2.0 + (rgba.
b
- rgba.
r
) / delta;
// between cyan & yellow
128
}
129
else
130
{
131
out.
h
= 4.0 + (rgba.
r
- rgba.
g
) / delta;
// between magenta & cyan
132
}
133
134
out.
h
*= 60.0;
// convert to degrees
135
136
if
(out.
h
< 0.0)
// convert to positive degrees
137
{
138
out.
h
+= 360.0;
139
}
140
out.
h
/= 360.0;
// convert to be [0, 1]
141
142
return
out;
143
}
144
145
color_util::ColorHSVA24
changeColorspace
(
const
color_util::ColorRGBA24
& rgba)
146
{
147
return
toInt
(
changeColorspace
(
toFloat
(rgba)));
148
}
149
150
color_util::ColorRGBA
changeColorspace
(
const
color_util::ColorHSVA
& hsva)
151
{
152
color_util::ColorRGBA
out;
153
154
// Alpha channel
155
out.
a
= hsva.
a
;
156
157
if
(hsva.
s
<= 0.0)
// < is invalid for valid input
158
{
159
// Grayscale
160
out.
r
= hsva.
v
;
161
out.
g
= hsva.
v
;
162
out.
b
= hsva.
v
;
163
return
out;
164
}
165
166
double
hh = hsva.
h
* 360.0;
167
if
(hh >= 360.0) hh = 0.0;
168
hh /= 60.0;
169
170
int
i =
static_cast<
int
>
(hh);
171
double
ff = hh - i;
172
double
p = hsva.
v
* (1.0 - hsva.
s
);
173
double
q = hsva.
v
* (1.0 - (hsva.
s
* ff));
174
double
t = hsva.
v
* (1.0 - (hsva.
s
* (1.0 - ff)));
175
176
switch
(i)
177
{
178
case
0:
179
out.
r
= hsva.
v
;
180
out.
g
= t;
181
out.
b
= p;
182
break
;
183
case
1:
184
out.
r
= q;
185
out.
g
= hsva.
v
;
186
out.
b
= p;
187
break
;
188
case
2:
189
out.
r
= p;
190
out.
g
= hsva.
v
;
191
out.
b
= t;
192
break
;
193
case
3:
194
out.
r
= p;
195
out.
g
= q;
196
out.
b
= hsva.
v
;
197
break
;
198
case
4:
199
out.
r
= t;
200
out.
g
= p;
201
out.
b
= hsva.
v
;
202
break
;
203
case
5:
204
default
:
205
out.
r
= hsva.
v
;
206
out.
g
= p;
207
out.
b
= q;
208
break
;
209
}
210
return
out;
211
}
212
213
color_util::ColorRGBA24
changeColorspace
(
const
color_util::ColorHSVA24
& hsva)
214
{
215
return
toInt
(
changeColorspace
(
toFloat
(hsva)));
216
}
217
218
std_msgs::ColorRGBA
toMsg
(
const
color_util::ColorRGBA
& rgba)
219
{
220
std_msgs::ColorRGBA msg;
221
msg.r = rgba.
r
;
222
msg.g = rgba.
g
;
223
msg.b = rgba.
b
;
224
msg.a = rgba.
a
;
225
return
msg;
226
}
227
228
std_msgs::ColorRGBA
toMsg
(
const
color_util::ColorRGBA24
& rgba)
229
{
230
return
toMsg
(
toFloat
(rgba));
231
}
232
233
std_msgs::ColorRGBA
toMsg
(
const
color_util::ColorHSVA
& hsva)
234
{
235
return
toMsg
(
changeColorspace
(hsva));
236
}
237
238
std_msgs::ColorRGBA
toMsg
(
const
color_util::ColorHSVA24
& hsva)
239
{
240
return
toMsg
(
changeColorspace
(hsva));
241
}
242
243
244
}
// namespace color_util
color_util::ColorRGBA24
Definition:
types.h:89
color_util::toFloat
color_util::ColorRGBA toFloat(const color_util::ColorRGBA24 &int_color)
Definition:
convert.cpp:45
color_util::GenericColorHSVA::v
T v
Definition:
types.h:74
color_util::GenericColorRGBA::r
T r
Definition:
types.h:54
color_util::ColorHSVA24
Definition:
types.h:102
color_util::GenericColorHSVA::s
T s
Definition:
types.h:74
color_util
Definition:
blend.h:41
color_util::GenericColorHSVA::a
T a
Definition:
types.h:74
color_util::ColorRGBA
Definition:
types.h:83
convert.h
color_util::changeColorspace
color_util::ColorHSVA changeColorspace(const color_util::ColorRGBA &rgba)
Definition:
convert.cpp:92
color_util::GenericColorRGBA::b
T b
Definition:
types.h:54
color_util::GenericColorHSVA::h
T h
Definition:
types.h:74
color_util::ColorHSVA
Definition:
types.h:96
color_util::GenericColorRGBA::g
T g
Definition:
types.h:54
color_util::toInt
color_util::ColorRGBA24 toInt(const color_util::ColorRGBA &float_color)
Definition:
convert.cpp:70
color_util::GenericColorRGBA::a
T a
Definition:
types.h:54
color_util::toMsg
std_msgs::ColorRGBA toMsg(const color_util::ColorRGBA &rgba)
Definition:
convert.cpp:218
color_util
Author(s):
autogenerated on Sun May 18 2025 02:47:14