10#ifndef MVE_IMAGE_COLOR_HEADER
11#define MVE_IMAGE_COLOR_HEADER
37template <
typename T,
typename FUNCTOR>
39color_convert (
typename Image<T>::Ptr image, FUNCTOR& converter);
131template <
typename T,
typename FUNCTOR>
135 int64_t
const channels = image->
channels();
137 throw std::invalid_argument(
"Only 3-channel images supported");
139 for (T* ptr = image->
begin(); ptr != image->
end(); ptr += channels)
148 out[0] = v[0] * T(0.4124) + v[1] * T(0.3576) + v[2] * T(0.1805);
149 out[1] = v[0] * T(0.2126) + v[1] * T(0.7152) + v[2] * T(0.0722);
150 out[2] = v[0] * T(0.0193) + v[1] * T(0.1192) + v[2] * T(0.9505);
151 std::copy_n(out, 3, v);
156color_srgb_to_xyz<uint8_t> (uint8_t* v)
159 out[0] = v[0] * 0.4124 + v[1] * 0.3576 + v[2] * 0.1805;
160 out[1] = v[0] * 0.2126 + v[1] * 0.7152 + v[2] * 0.0722;
161 out[2] = v[0] * 0.0193 + v[1] * 0.1192 + v[2] * 0.9505;
162 v[0] = std::max(0.0, std::min(255.0,
math::round(out[0])));
163 v[1] = std::max(0.0, std::min(255.0,
math::round(out[1])));
164 v[2] = std::max(0.0, std::min(255.0,
math::round(out[2])));
172 out[0] = v[0] * T( 3.2410) + v[1] * T(-1.5374) + v[2] * T(-0.4986);
173 out[1] = v[0] * T(-0.9692) + v[1] * T( 1.8760) + v[2] * T( 0.0416);
174 out[2] = v[0] * T( 0.0556) + v[1] * T(-0.2040) + v[2] * T( 1.0570);
175 std::copy_n(out, 3, v);
180color_xyz_to_srgb<uint8_t> (uint8_t* v)
183 out[0] = v[0] * 3.2410 + v[1] * -1.5374 + v[2] * -0.4986;
184 out[1] = v[0] * -0.9692 + v[1] * 1.8760 + v[2] * 0.0416;
185 out[2] = v[0] * 0.0556 + v[1] * -0.2040 + v[2] * 1.0570;
186 v[0] = std::max(0.0, std::min(255.0,
math::round(out[0])));
187 v[1] = std::max(0.0, std::min(255.0,
math::round(out[1])));
188 v[2] = std::max(0.0, std::min(255.0,
math::round(out[2])));
203 T
const ratio = v[2] / v[1];
205 out[0] = v[0] * ratio;
207 out[2] = (T(1) - v[0] - v[1]) * ratio;
208 std::copy_n(out, 3, v);
214color_xyy_to_xyz<uint8_t> (uint8_t* v)
224 double const ratio = v[2] /
static_cast<double>(v[1]);
226 out[0] = v[0] * ratio;
228 out[2] = (255 - v[0] - v[1]) * ratio;
229 v[0] = std::max(0.0, std::min(255.0,
math::round(out[0])));
230 v[1] = std::max(0.0, std::min(255.0,
math::round(out[1])));
231 v[2] = std::max(0.0, std::min(255.0,
math::round(out[2])));
239 T
const sum = v[0] + v[1] + v[2];
252 std::copy_n(out, 3, v);
258color_xyz_to_xyy<uint8_t> (uint8_t* v)
260 if (v[0] == 0 && v[1] == 0 && v[2] == 0)
268 double const sum = v[0] + v[1] + v[2];
270 out[0] = 255.0 * v[0] / sum;
271 out[1] = 255.0 * v[1] / sum;
272 out[2] =
static_cast<double>(v[1]);
273 v[0] = std::max(0.0, std::min(255.0,
math::round(out[0])));
274 v[1] = std::max(0.0, std::min(255.0,
math::round(out[1])));
275 v[2] = std::max(0.0, std::min(255.0,
math::round(out[2])));
284 out[0] = v[0] * T(0.299) + v[1] * T(0.587) + v[2] * T(0.114);
285 out[1] = v[0] * T(-0.168736) + v[1] * T(-0.331264) + v[2] * T(0.5) + T(0.5);
286 out[2] = v[0] * T(0.5) + v[1] * T(-0.418688) + v[2] * T(-0.081312) + T(0.5);
287 std::copy_n(out, 3, v);
292color_rgb_to_ycbcr<uint8_t> (uint8_t* v)
295 out[0] = v[0] * 0.299 + v[1] * 0.587 + v[2] * 0.114 + 0.0;
296 out[1] = v[0] * -0.168736 + v[1] * -0.331264 + v[2] * 0.5 + 128.0;
297 out[2] = v[0] * 0.5 + v[1] * -0.418688 + v[2] * -0.081312 + 128.0;
298 v[0] = std::max(0.0, std::min(255.0,
math::round(out[0])));
299 v[1] = std::max(0.0, std::min(255.0,
math::round(out[1])));
300 v[2] = std::max(0.0, std::min(255.0,
math::round(out[2])));
307 v[1] = v[1] - T(0.5);
308 v[2] = v[2] - T(0.5);
311 out[0] = v[0] * T(1) + v[1] * T(0) + v[2] * T(1.402);
312 out[1] = v[0] * T(1) + v[1] * T(-0.34414) + v[2] * T(-0.71414);
313 out[2] = v[0] * T(1) + v[1] * T(1.772) + v[2] * T(0);
314 std::copy_n(out, 3, v);
319color_ycbcr_to_rgb<uint8_t> (uint8_t* v)
322 out[0] = v[0] + 1.402 * (v[2] - 128.0);
323 out[1] = v[0] - 0.34414 * (v[1] - 128.0) - 0.71414 * (v[2] - 128.0);
324 out[2] = v[0] + 1.772 * (v[1] - 128.0);
325 v[0] = std::max(0.0, std::min(255.0,
math::round(out[0])));
326 v[1] = std::max(0.0, std::min(255.0,
math::round(out[1])));
327 v[2] = std::max(0.0, std::min(255.0,
math::round(out[2])));
int64_t channels(void) const
Returns the amount of channels in the image.
std::shared_ptr< Image< T > > Ptr
T * begin(void)
Returns data pointer to beginning.
T * end(void)
Returns data pointer to end.
#define MVE_IMAGE_NAMESPACE_END
#define MVE_NAMESPACE_BEGIN
#define MVE_IMAGE_NAMESPACE_BEGIN
#define MVE_NAMESPACE_END
T round(T const &x)
Removes the fractional part of the value to the closest integer.
void color_srgb_to_xyz(T *values)
Converts linear sRGB values RGB into XYZ (CIE 1931) according to http://www.w3.org/Graphics/Color/sRG...
void color_xyy_to_xyz(T *values)
Converts xyY colors to XYZ (CIE 1931) coordinates according to http://www.brucelindbloom....
void color_rgb_to_ycbcr(T *values)
Converts an image from RGB to YCbCr color space according to http://en.wikipedia.org/wiki/YCbCr.
void color_xyz_to_xyy(T *values)
Converts XYZ colors to xyY coordinates according to http://www.brucelindbloom.com/index....
void color_ycbcr_to_rgb(T *values)
Converts an image from YCbCr to RGB color space according to http://en.wikipedia.org/wiki/YCbCr.
void color_xyz_to_srgb(T *values)
Converts XYZ into linear sRGB values RGB according to http://www.w3.org/Graphics/Color/sRGB.
void color_convert(typename Image< T >::Ptr image, FUNCTOR &converter)
Applies an in-place color conversion to the given image.