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 
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 
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 
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 
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
93 {
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 
146 {
147  return toInt(changeColorspace(toFloat(rgba)));
148 }
149 
151 {
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 
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::ColorHSVA changeColorspace(const color_util::ColorRGBA &rgba)
Definition: convert.cpp:92
std_msgs::ColorRGBA toMsg(const color_util::ColorRGBA &rgba)
Definition: convert.cpp:218
color_util::ColorRGBA24 toInt(const color_util::ColorRGBA &float_color)
Definition: convert.cpp:70
color_util::ColorRGBA toFloat(const color_util::ColorRGBA24 &int_color)
Definition: convert.cpp:45


color_util
Author(s):
autogenerated on Sun Jan 10 2021 04:08:24