libcrn  3.9.5
A document image processing library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CRNPixel.h
Go to the documentation of this file.
1 /* Copyright 2015-2016 INSA-Lyon
2  *
3  * This file is part of libcrn.
4  *
5  * libcrn is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * libcrn is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with libcrn. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * file: CRNPixel.h
19  * \author Yann LEYDIER
20  */
21 
22 #ifndef CRNPixel_HEADER
23 #define CRNPixel_HEADER
24 
25 #include <CRNMath/CRNMath.h>
26 
30 namespace crn
31 {
34 
35  /*************************************************************
36  * Black & White
37  ************************************************************/
38  namespace pixel
39  {
40  using BW = bool;
41  static constexpr BW BWWhite = true;
42  static constexpr BW BWBlack = false;
43  }
44 
45  /*************************************************************
46  * RGB
47  ************************************************************/
48  namespace pixel
49  {
50  struct HSV;
51  struct XYZ;
52  struct YUV;
53  struct Lab;
54  struct Luv;
55  template<typename T> struct RGB
56  {
57  using type = T;
58  constexpr RGB() noexcept {}
59  constexpr RGB(T val) noexcept: r(val), g(val), b(val) {}
60  constexpr RGB(T r_, T g_, T b_) noexcept: r(r_), g(g_), b(b_) {}
61  template<typename Y> constexpr RGB(const RGB<Y> &p) noexcept: r(T(p.r)), g(T(p.g)), b(T(p.b)) {}
62  RGB(const HSV &val) noexcept;
63  RGB(const XYZ &p) noexcept;
64  RGB(const YUV &p) noexcept;
65  RGB(const Lab &p) noexcept;
66  RGB(const Luv &p) noexcept;
67 
68  // bitwise sort
69  inline bool operator<(const RGB &other) const noexcept
70  {
71  if (r < other.r) return true;
72  else if (r == other.r)
73  {
74  if (g < other.g) return true;
75  else if (g == other.g)
76  return b < other.b;
77  }
78  return false;
79  }
80  constexpr bool operator==(const RGB &other) const noexcept { return (r == other.r) && (g == other.g) && (b == other.b); }
81  constexpr bool operator!=(const RGB &other) const noexcept { return !(*this == other); }
82  RGB& operator+=(const RGB &other) { r += other.r; g += other.g; b += other.b; return *this; }
83  RGB& operator-=(const RGB &other) { r -= other.r; g -= other.g; b -= other.b; return *this; }
84 
85  T r = 0, g = 0, b = 0;
86  };
87  using RGB8 = RGB<uint8_t>;
88  } // namespace pixel
89 
90  template<typename I> struct TypeInfo<pixel::RGB<I>>
91  {
95  };
96 
97  namespace pixel
98  {
99  template<typename T> constexpr crn::SumType<crn::pixel::RGB<T>> operator+(const crn::pixel::RGB<T> &p1, const crn::pixel::RGB<T> &p2)
100  {
101  return crn::SumType<crn::pixel::RGB<T>>{p1.r + p2.r, p1.g + p2.g, p1.b + p2.b};
102  }
103  template<typename T> constexpr crn::DiffType<crn::pixel::RGB<T>> operator-(const crn::pixel::RGB<T> &p1, const crn::pixel::RGB<T> &p2)
104  {
105  return crn::DiffType<crn::pixel::RGB<T>>{p1.r - p2.r, p1.g - p2.g, p1.b - p2.b};
106  }
107  template<typename T> constexpr crn::DecimalType<crn::pixel::RGB<T>> operator*(const crn::pixel::RGB<T> &p, double d)
108  {
109  return crn::DecimalType<crn::pixel::RGB<T>>{p.r * d, p.g * d, p.b * d};
110  }
111  template<typename T> constexpr crn::DecimalType<crn::pixel::RGB<T>> operator*(double d, const crn::pixel::RGB<T> &p)
112  {
113  return crn::DecimalType<crn::pixel::RGB<T>>{p.r * d, p.g * d, p.b * d};
114  }
115  template<typename T> constexpr crn::DecimalType<crn::pixel::RGB<T>> operator/(const crn::pixel::RGB<T> &p, double d)
116  {
117  return crn::DecimalType<crn::pixel::RGB<T>>{p.r / d, p.g / d, p.b / d};
118  }
119 
120  template<typename T> crn::SumType<T> Abs(const crn::pixel::RGB<T> &p)
121  {
122  return crn::Abs(p.r) + crn::Abs(p.g) + crn::Abs(p.b);
123  }
124  } // namespace pixel
125 
126 } // namespace crn
129 namespace std
130 {
131  template<typename T> class numeric_limits<crn::pixel::RGB<T>>
132  {
133  public:
134  static constexpr bool is_specialized = true;
135  static constexpr crn::pixel::RGB<T> min() noexcept { return numeric_limits<T>::min(); }
136  static constexpr crn::pixel::RGB<T> max() noexcept { return numeric_limits<T>::max(); }
137  static constexpr crn::pixel::RGB<T> lowest() noexcept { return numeric_limits<T>::lowest(); }
138  static constexpr int digits = numeric_limits<T>::digits;
139  static constexpr int digits10 = numeric_limits<T>::digits10;
140  static constexpr bool is_signed = numeric_limits<T>::is_signed;
141  static constexpr bool is_integer = numeric_limits<T>::is_integer;
142  static constexpr bool is_exact = numeric_limits<T>::is_exact;
143  static constexpr int radix = numeric_limits<T>::radix;
144  static constexpr crn::pixel::RGB<T> epsilon() noexcept { return numeric_limits<T>::epsilon(); }
145  static constexpr crn::pixel::RGB<T> round_error() noexcept { return numeric_limits<T>::round_error(); }
146 
147  static constexpr int min_exponent = numeric_limits<T>::min_exponent;
148  static constexpr int min_exponent10 = numeric_limits<T>::min_exponent10;
149  static constexpr int max_exponent = numeric_limits<T>::max_exponent;
150  static constexpr int max_exponent10 = numeric_limits<T>::max_exponent10;
151 
152  static constexpr bool has_infinity = numeric_limits<T>::has_infinity;
153  static constexpr bool has_quiet_NaN = numeric_limits<T>::has_quiet_NaN;
154  static constexpr bool has_signaling_NaN = numeric_limits<T>::has_signaling_NaN;
155  static constexpr float_denorm_style has_denorm = numeric_limits<T>::has_denorm;
156  static constexpr bool has_denorm_loss = numeric_limits<T>::has_denorm_loss;
157  static constexpr crn::pixel::RGB<T> infinity() noexcept { return numeric_limits<T>::infinity(); }
158  static constexpr crn::pixel::RGB<T> quiet_NaN() noexcept { return numeric_limits<T>::quiet_NaN(); }
159  static constexpr crn::pixel::RGB<T> signaling_NaN() noexcept { return numeric_limits<T>::signaling_NaN(); }
160  static constexpr crn::pixel::RGB<T> denorm_min() noexcept { return numeric_limits<T>::denorm_min(); }
161 
162  static constexpr bool is_iec559 = numeric_limits<T>::is_iec559;
163  static constexpr bool is_bounded = numeric_limits<T>::is_bounded;
164  static constexpr bool is_modulo = numeric_limits<T>::is_modulo;
165 
166  static constexpr bool traps = numeric_limits<T>::traps;
167  static constexpr bool tinyness_before = numeric_limits<T>::tinyness_before;
168  static constexpr float_round_style round_style = numeric_limits<T>::round_style;
169  };
170 } // namespace std
171 
172 /*************************************************************
173  * HSV
174  ************************************************************/
175 namespace crn
176 {
179  namespace pixel
180  {
181  struct HSV
182  {
183  constexpr HSV() noexcept {}
184  constexpr HSV(uint8_t h_, uint8_t s_, uint8_t v_) noexcept: h(h_), s(s_), v(v_) {}
185  constexpr HSV(uint8_t v_) noexcept: v(v_) {}
186  HSV(const RGB<uint8_t> &val) noexcept
187  {
188  auto max = Max(val.r, val.g, val.b);
189  auto min = Min(val.r, val.g, val.b);
190  auto diff = max - min;
191 
192  auto hue = 0.0;
193  auto coeffh = 255.0 / 360.0;
194  if (max == 0)
195  hue = 0;
196  else
197  {
198  if (max != min)
199  {
200  if (max == val.r)
201  {
202  hue = 60 * (( val.g / 255.0 - val.b / 255.0 ) / (diff / 255.0));
203  }
204  else if (max == val.g)
205  {
206  hue = 60 * ((val.b / 255.0 - val.r / 255.0) / (diff / 255.0)) + 120;
207  }
208  else
209  {
210  hue = 60 * ((val.r / 255.0 - val.g / 255.0) / (diff / 255.0)) + 240;
211  }
212  }
213  if (hue < 0) hue += 360;
214  }
215  hue *= coeffh;
216  h = (uint8_t)hue;
217  auto sat = 0.0;
218  auto coeffs = 255.0;
219  if (max > 0)
220  sat = 1.0 - (double(min) / max);
221  s = uint8_t(sat * coeffs);
222  v = uint8_t(max);
223  }
224  // bitwise sort
225  bool operator<(const HSV &other) const noexcept
226  {
227  if (h < other.h) return true;
228  else if (h == other.h)
229  {
230  if (s < other.s) return true;
231  else if (s == other.s)
232  return v < other.v;
233  }
234  return false;
235  }
236  constexpr bool operator==(const HSV &other) const noexcept { return (h == other.h) && (s == other.s) && (v == other.v); }
237  constexpr bool operator!=(const HSV &other) const noexcept { return !(*this == other); }
238  uint8_t h = 0, s = 0, v = 0;
239  };
240 
241  template<typename T> RGB<T>::RGB(const HSV &val) noexcept
242  {
243  auto hue = double(val.h) / 42.5;
244  if (hue == 6) hue = 0;
245  auto i = int(hue);
246  auto v1 = int(val.v) * (255 - val.s) / 255;
247  auto v2 = int(val.v * (255 - val.s * (hue - i)) / 255);
248  auto v3 = int(val.v * (255 - val.s * (1 - (hue - i))) / 255);
249  switch (i)
250  {
251  case 0:
252  r = T(val.v);
253  g = T(v3);
254  b = T(v1);
255  break;
256  case 1:
257  r = T(v2);
258  g = T(val.v);
259  b = T(v1);
260  break;
261  case 2:
262  r = T(v1);
263  g = T(val.v);
264  b = T(v3);
265  break;
266  case 3:
267  r = T(v1);
268  g = T(v2);
269  b = T(val.v);
270  break;
271  case 4:
272  r = T(v3);
273  g = T(v1);
274  b = T(val.v);
275  break;
276  default:
277  r = T(val.v);
278  g = T(v1);
279  b = T(v2);
280  }
281  }
282  } // namespace pixel
283 
284  template<> struct TypeInfo<pixel::HSV>
285  {
289  };
290 
291  namespace pixel
292  {
294  {
296  }
298  {
300  }
302  {
303  return crn::pixel::RGB<uint8_t>(p) * d;
304  }
306  {
307  return crn::pixel::RGB<uint8_t>(p) * d;
308  }
310  {
311  return crn::pixel::RGB<uint8_t>(p) / d;
312  }
313  } // namespace pixel
314 } // namespace crn
317 /*************************************************************
318  * 2D Cartesian vector
319  ************************************************************/
320 namespace crn
321 {
324  namespace pixel
325  {
326  template<typename R, typename T> struct Polar2D;
327 
328  template<typename T> struct Cart2D
329  {
330  using type = T;
331  constexpr Cart2D() noexcept {}
332  constexpr Cart2D(T x_, T y_ = 0) noexcept: x(x_), y(y_) {}
333  Cart2D(const std::complex<double> &cx) : x(T(cx.real())), y(T(cx.imag())) {}
334  template<typename Y> constexpr Cart2D(const Cart2D<Y> &p) noexcept: x(p.x), y(p.y) {}
335  template<typename Y, typename Z> Cart2D(const Polar2D<Y, Z> &p);
336  operator std::complex<double>() const { return {double(x), double(y)}; }
337 
338  // bitwise sort
339  bool operator<(const Cart2D &other) const noexcept
340  {
341  if (x < other.x) return true;
342  else if (x == other.x) return y < other.y;
343  return false;
344  }
345  constexpr bool operator==(const Cart2D &other) const noexcept { return (x == other.x) && (y == other.y); }
346  constexpr bool operator!=(const Cart2D &other) const noexcept { return !(*this == other); }
347  Cart2D& operator+=(const Cart2D &other) { x += other.x; y += other.y; return *this; }
348 
349  T x = 0, y = 0;
350  };
351  } // namespace pixel
352 
353  template<typename I> struct TypeInfo<pixel::Cart2D<I>>
354  {
358  };
359 
360  namespace pixel
361  {
362  template<typename T> constexpr crn::SumType<crn::pixel::Cart2D<T>> operator+(const crn::pixel::Cart2D<T> &p1, const crn::pixel::Cart2D<T> &p2)
363  {
364  return crn::SumType<crn::pixel::Cart2D<T>>{p1.x + p2.x, p1.y + p2.y};
365  }
366  template<typename T> constexpr crn::DiffType<crn::pixel::Cart2D<T>> operator-(const crn::pixel::Cart2D<T> &p1, const crn::pixel::Cart2D<T> &p2)
367  {
368  return crn::DiffType<crn::pixel::Cart2D<T>>{p1.x - p2.x, p1.y - p2.y};
369  }
370  template<typename T> constexpr crn::DecimalType<crn::pixel::Cart2D<T>> operator*(const crn::pixel::Cart2D<T> &p, double d)
371  {
372  return crn::DecimalType<crn::pixel::Cart2D<T>>{p.x * d, p.y * d};
373  }
374  template<typename T> constexpr crn::DecimalType<crn::pixel::Cart2D<T>> operator*(double d, const crn::pixel::Cart2D<T> &p)
375  {
376  return crn::DecimalType<crn::pixel::Cart2D<T>>{p.x * d, p.y * d};
377  }
378  template<typename T> constexpr crn::DecimalType<crn::pixel::Cart2D<T>> operator/(const crn::pixel::Cart2D<T> &p, double d)
379  {
380  return crn::DecimalType<crn::pixel::Cart2D<T>>{p.x / d, p.y / d};
381  }
382  } // namespace pixel
383 } // namespace crn
386 #include <CRNMath/CRNMath.h>
387 
388 /*************************************************************
389  * 2D polar vector
390  ************************************************************/
391 namespace crn
392 {
395  namespace pixel
396  {
397  template<typename R, typename T> struct Polar2D
398  {
399  using rho_type = R;
400  using theta_type = T;
401  constexpr Polar2D() noexcept {}
402  constexpr Polar2D(R r, T t = 0) noexcept: rho(r), theta(t) {}
403  Polar2D(const std::complex<double> &cx) : rho(R(std::abs(cx))), theta(T(std::arg(cx))) { }
404  template<typename Y, typename Z> constexpr Polar2D(const Polar2D<Y, Z> &p) noexcept: rho(R(p.rho)), theta(T(p.theta)) {}
405  template<typename Y> Polar2D(const Cart2D<Y> &p): rho(R(sqrt(typename std::common_type<R, double>::type(Sqr(p.x) + Sqr(p.y))))), theta(T::Atan(typename std::common_type<R, double>::type(p.y), typename std::common_type<R, double>::type(p.x))) {}
406  operator std::complex<double>() const { return std::complex<double>(Cart2D<double>(*this)); }
407 
408  // bitwise sort
409  bool operator<(const Polar2D &other) const noexcept
410  {
411  if (rho < other.rho) return true;
412  else if (rho == other.rho) return theta.value < other.theta.value;
413  return false;
414  }
415  constexpr bool operator==(const Polar2D &other) const noexcept { return (rho == other.rho) && (theta == other.theta); }
416  constexpr bool operator!=(const Polar2D &other) const noexcept { return !(*this == other); }
418 
419  R rho = 0;
420  T theta = 0;
421  };
422 
423  template<typename T> template<typename Y, typename Z> Cart2D<T>::Cart2D(const Polar2D<Y, Z> &p):
424  x(T(p.rho * Cos(p.theta))),
425  y(T(p.rho * Sin(p.theta)))
426  { }
427  } // namespace pixel
428 
429  template<typename I, typename J> struct TypeInfo<pixel::Polar2D<I, J>>
430  {
434  };
435 
436  namespace pixel
437  {
438  template<typename R, typename T> constexpr crn::SumType<crn::pixel::Polar2D<R, T>> operator+(const crn::pixel::Polar2D<R, T> &p1, const crn::pixel::Polar2D<R, T> &p2)
439  {
441  }
442  template<typename R, typename T> constexpr crn::DiffType<crn::pixel::Polar2D<R, T>> operator-(const crn::pixel::Polar2D<R, T> &p1, const crn::pixel::Polar2D<R, T> &p2)
443  {
445  }
446  template<typename R, typename T> constexpr crn::DecimalType<crn::pixel::Polar2D<R, T>> operator*(const crn::pixel::Polar2D<R, T> &p, double d)
447  {
449  }
450  template<typename R, typename T> constexpr crn::DecimalType<crn::pixel::Polar2D<R, T>> operator*(double d, const crn::pixel::Polar2D<R, T> &p)
451  {
453  }
454  template<typename R, typename T> constexpr crn::DecimalType<crn::pixel::Polar2D<R, T>> operator/(const crn::pixel::Polar2D<R, T> &p, double d)
455  {
457  }
458  } // namespace pixel
459 } // namespace crn
462 /*************************************************************
463  * XYZ real values from CIE 1931 model. Observer. = 2°, Illuminant = D65
464  ************************************************************/
465 namespace crn
466 {
469  namespace pixel
470  {
471  struct Lab;
472  struct Luv;
473 
474  struct XYZ
475  {
476  constexpr XYZ() {}
477  constexpr XYZ(double x_, double y_ = 0.0, double z_ = 0.0): x(x_), y(y_), z(z_) {}
478  XYZ(const RGB<uint8_t> &p);
479  XYZ(const Lab &p);
480  XYZ(const Luv &p);
481 
482  double x = 0.0, y = 0.0, z = 0.0;
483  };
484 
485  template<typename T> RGB<T>::RGB(const XYZ &val) noexcept
486  {
487  auto var_X = val.x / 100;
488  auto var_Y = val.y / 100;
489  auto var_Z = val.z / 100;
490 
491  auto var_R = var_X * 3.2406 + var_Y * -1.5372 + var_Z * -0.4986;
492  auto var_G = var_X * -0.9689 + var_Y * 1.8758 + var_Z * 0.0415;
493  auto var_B = var_X * 0.0557 + var_Y * -0.2040 + var_Z * 1.0570;
494 
495  if (var_R > 0.0031308)
496  var_R = 1.055 * pow(var_R, 1 / 2.4) - 0.055;
497  else
498  var_R *= 12.92;
499  if (var_G > 0.0031308)
500  var_G = 1.055 * pow(var_G, 1 / 2.4) - 0.055;
501  else
502  var_G *= 12.92;
503  if (var_B > 0.0031308)
504  var_B = 1.055 * pow(var_B, 1 / 2.4) - 0.055;
505  else
506  var_B *= 12.92;
507 
508  r = T(Cap((int)(var_R * 255), 0, 255));
509  g = T(Cap((int)(var_G * 255), 0, 255));
510  b = T(Cap((int)(var_B * 255), 0, 255));
511  }
512  }
515 } // namespace crn
516 
517 /*************************************************************
518  * YUV real values
519  ************************************************************/
520 
521 namespace crn
522 {
525  namespace pixel
526  {
527  struct YUV
528  {
529  constexpr YUV() {}
530  constexpr YUV(double y_, double u_ = 0.0, double v_ = 0.0): y(y_), u(u_), v(v_) {}
531  YUV(const RGB<uint8_t> &p);
532 
533  constexpr bool operator==(const YUV &other) const noexcept { return (y == other.y) && (u == other.u) && (v == other.v); }
534  constexpr bool operator!=(const YUV &other) const noexcept { return !(*this == other); }
535  YUV& operator+=(const YUV &other) { y += other.y; u += other.u; v += other.v; return *this; }
536  YUV& operator-=(const YUV &other) { y -= other.y; u -= other.u; v -= other.v; return *this; }
537 
538  double y = 0.0, u = 0.0, v = 0.0;
539  };
540 
541  template<typename T> RGB<T>::RGB(const YUV &val) noexcept
542  {
543  auto var_R = val.y + 1.13983 * val.v;
544  auto var_G = val.y - 0.39465 * val.u - 0.58060 * val.v;
545  auto var_B = val.y + 2.03211 * val.u;
546 
547  r = T(Cap((int)(var_R * 255), 0, 255));
548  g = T(Cap((int)(var_G * 255), 0, 255));
549  b = T(Cap((int)(var_B * 255), 0, 255));
550  }
551  } // namespace pixel
552 
553  template<> struct TypeInfo<pixel::YUV>
554  {
558  };
559 
560  namespace pixel
561  {
563  {
564  return crn::pixel::YUV{p1.y - p2.y, p1.u - p2.u, p1.v - p2.v};
565  }
567  {
568  return crn::pixel::YUV{p1.y - p2.y, p1.u - p2.u, p1.v - p2.v};
569  }
570  constexpr crn::pixel::YUV operator*(const crn::pixel::YUV &p, double d)
571  {
572  return crn::pixel::YUV{p.y * d, p.u * d, p.v * d};
573  }
574  constexpr crn::pixel::YUV operator*(double d, const crn::pixel::YUV &p)
575  {
576  return crn::pixel::YUV{p.y * d, p.u * d, p.v * d};
577  }
578  constexpr crn::pixel::YUV operator/(const crn::pixel::YUV &p, double d)
579  {
580  return crn::pixel::YUV{p.y / d, p.u / d, p.v / d};
581  }
582  } // namespace pixel
584 } // namespace crn
585 
586 /*************************************************************
587  * Lab real values from CIE 1976 L*a*b* model. Observer= 2°, Illuminant= D65
588  ************************************************************/
589 namespace crn
590 {
593  namespace pixel
594  {
595  struct Lab
596  {
597  constexpr Lab() {}
598  constexpr Lab(double l_, double a_ = 0.0, double b_ = 0.0): l(l_), a(a_), b(b_) {}
599  Lab(const XYZ &p);
600 
601  Lab& operator+=(const Lab &p)
602  {
603  const auto s = RGB8(*this) + RGB8(p);
604  *this = XYZ{RGB8{s}};
605  return *this;
606  }
607 
608  double l = 0.0, a = 0.0, b = 0.0;
609  };
610 
611  template<typename T> RGB<T>::RGB(const Lab &val) noexcept
612  {
613  *this = XYZ(val);
614  }
615 
617  {
619  }
621  {
623  }
624  inline crn::pixel::Lab operator*(double d, const crn::pixel::Lab &p)
625  {
626  return crn::pixel::Lab{ p.l * d, p.a, p.b };
627  }
628  inline crn::pixel::Lab operator/(const crn::pixel::Lab &p, double d)
629  {
630  return crn::pixel::Lab{ p.l / d, p.a, p.b };
631  }
632  } // namespace pixel
633 } // namespace crn
636 /*************************************************************
637  * Luv real values from CIE 1976 L*u*v* model. Observer= 2°, Illuminant= D65
638  ************************************************************/
639 namespace crn
640 {
643  namespace pixel
644  {
645  struct Luv
646  {
647  constexpr Luv() {}
648  constexpr Luv(double l_, double u_ = 0.0, double v_ = 0.0): l(l_), u(u_), v(v_) {}
649  Luv(const XYZ &p);
650 
651  Luv& operator+=(const Luv &p)
652  {
653  *this = XYZ{RGB8{RGB8(*this) + RGB8(p)}};
654  return *this;
655  }
656 
657  double l = 0.0, u = 0.0, v = 0.0;
658  };
659  template<typename T> RGB<T>::RGB(const Luv &val) noexcept
660  {
661  *this = XYZ(val);
662  }
664  {
666  }
668  {
670  }
671  inline crn::pixel::Luv operator*(double d, const crn::pixel::Luv &p)
672  {
673  return crn::pixel::Luv{ p.l * d, p.u, p.v };
674  }
675  inline crn::pixel::Luv operator/(const crn::pixel::Luv &p, double d)
676  {
677  return crn::pixel::Luv{ p.l / d, p.u, p.v };
678  }
679  } // namespace pixel
680 } // namespace crn
683 #endif
684 
685 
typename TypeInfo< T >::SumType SumType
Definition: CRNType.h:185
constexpr bool operator!=(const HSV &other) const noexcept
Definition: CRNPixel.h:237
constexpr HSV(uint8_t h_, uint8_t s_, uint8_t v_) noexcept
Definition: CRNPixel.h:184
constexpr Polar2D(const Polar2D< Y, Z > &p) noexcept
Definition: CRNPixel.h:404
Cart2D(const std::complex< double > &cx)
Definition: CRNPixel.h:333
static constexpr crn::pixel::RGB< T > infinity() noexcept
Definition: CRNPixel.h:157
constexpr Cart2D(T x_, T y_=0) noexcept
Definition: CRNPixel.h:332
constexpr bool operator==(const Cart2D &other) const noexcept
Definition: CRNPixel.h:345
constexpr RGB(T val) noexcept
Definition: CRNPixel.h:59
constexpr XYZ(double x_, double y_=0.0, double z_=0.0)
Definition: CRNPixel.h:477
const T & Cap(const T &v, const T &min, const T &max)
Bounds a value to an interval.
Definition: CRNMath.h:75
Cart2D & operator+=(const Cart2D &other)
Definition: CRNPixel.h:347
double Cos(const A &a) noexcept
constexpr bool operator==(const YUV &other) const noexcept
Definition: CRNPixel.h:533
constexpr Cart2D() noexcept
Definition: CRNPixel.h:331
static constexpr crn::pixel::RGB< T > max() noexcept
Definition: CRNPixel.h:136
const T & Max(const T &a, const T &b)
Returns the max of two values.
Definition: CRNMath.h:47
constexpr bool operator==(const RGB &other) const noexcept
Definition: CRNPixel.h:80
constexpr bool operator!=(const Polar2D &other) const noexcept
Definition: CRNPixel.h:416
crn::SumType< T > Abs(const crn::pixel::RGB< T > &p)
Definition: CRNPixel.h:120
constexpr Luv(double l_, double u_=0.0, double v_=0.0)
Definition: CRNPixel.h:648
constexpr YUV(double y_, double u_=0.0, double v_=0.0)
Definition: CRNPixel.h:530
constexpr bool operator!=(const YUV &other) const noexcept
Definition: CRNPixel.h:534
static constexpr crn::pixel::RGB< T > min() noexcept
Definition: CRNPixel.h:135
bool operator<(const RGB &other) const noexcept
Definition: CRNPixel.h:69
static constexpr crn::pixel::RGB< T > epsilon() noexcept
Definition: CRNPixel.h:144
RGB & operator-=(const RGB &other)
Definition: CRNPixel.h:83
constexpr bool operator==(const HSV &other) const noexcept
Definition: CRNPixel.h:236
static constexpr crn::pixel::RGB< T > round_error() noexcept
Definition: CRNPixel.h:145
bool operator<(const Cart2D &other) const noexcept
Definition: CRNPixel.h:339
HSV(const RGB< uint8_t > &val) noexcept
Definition: CRNPixel.h:186
constexpr crn::SumType< crn::pixel::RGB< T > > operator+(const crn::pixel::RGB< T > &p1, const crn::pixel::RGB< T > &p2)
Definition: CRNPixel.h:99
constexpr Cart2D(const Cart2D< Y > &p) noexcept
Definition: CRNPixel.h:334
RGB & operator+=(const RGB &other)
Definition: CRNPixel.h:82
Luv & operator+=(const Luv &p)
Definition: CRNPixel.h:651
Lab & operator+=(const Lab &p)
Definition: CRNPixel.h:601
constexpr Lab(double l_, double a_=0.0, double b_=0.0)
Definition: CRNPixel.h:598
static constexpr crn::pixel::RGB< T > denorm_min() noexcept
Definition: CRNPixel.h:160
static constexpr crn::pixel::RGB< T > quiet_NaN() noexcept
Definition: CRNPixel.h:158
constexpr bool operator==(const Polar2D &other) const noexcept
Definition: CRNPixel.h:415
bool operator<(const HSV &other) const noexcept
Definition: CRNPixel.h:225
constexpr RGB(T r_, T g_, T b_) noexcept
Definition: CRNPixel.h:60
constexpr Luv()
Definition: CRNPixel.h:647
constexpr SumType< T > Sqr(const T &v) noexcept(noexcept(v *v))
Returns the square of a value.
Definition: CRNMath.h:61
constexpr Polar2D(R r, T t=0) noexcept
Definition: CRNPixel.h:402
constexpr HSV() noexcept
Definition: CRNPixel.h:183
bool operator<(const Polar2D &other) const noexcept
Definition: CRNPixel.h:409
A Atan(double s, double c) noexcept
static constexpr crn::pixel::RGB< T > lowest() noexcept
Definition: CRNPixel.h:137
typename TypeInfo< T >::DecimalType DecimalType
Definition: CRNType.h:187
bool BW
Definition: CRNPixel.h:40
Definition: CRNImage.cpp:62
YUV & operator+=(const YUV &other)
Definition: CRNPixel.h:535
constexpr RGB() noexcept
Definition: CRNPixel.h:58
void Abs(Image< T > &img, typename std::enable_if< std::is_arithmetic< T >::value >::type *dummy=nullptr) noexcept
Replaces each pixel by its absolute value.
Definition: CRNImageGray.h:47
typename TypeInfo< T >::DiffType DiffType
Definition: CRNType.h:186
Polar2D & operator+=(const Polar2D &other)
Definition: CRNPixel.h:417
const T & Min(const T &a, const T &b)
Returns the min of two values.
Definition: CRNMath.h:49
constexpr bool operator!=(const Cart2D &other) const noexcept
Definition: CRNPixel.h:346
YUV & operator-=(const YUV &other)
Definition: CRNPixel.h:536
Polar2D(const std::complex< double > &cx)
Definition: CRNPixel.h:403
constexpr crn::DecimalType< crn::pixel::RGB< T > > operator*(const crn::pixel::RGB< T > &p, double d)
Definition: CRNPixel.h:107
constexpr RGB(const RGB< Y > &p) noexcept
Definition: CRNPixel.h:61
double Sin(const A &a) noexcept
constexpr Lab()
Definition: CRNPixel.h:597
static constexpr crn::pixel::RGB< T > signaling_NaN() noexcept
Definition: CRNPixel.h:159
constexpr bool operator!=(const RGB &other) const noexcept
Definition: CRNPixel.h:81
constexpr YUV()
Definition: CRNPixel.h:529
RGB< uint8_t > RGB8
Definition: CRNPixel.h:87
constexpr crn::DecimalType< crn::pixel::RGB< T > > operator/(const crn::pixel::RGB< T > &p, double d)
Definition: CRNPixel.h:115
constexpr crn::DiffType< crn::pixel::RGB< T > > operator-(const crn::pixel::RGB< T > &p1, const crn::pixel::RGB< T > &p2)
Definition: CRNPixel.h:103
Polar2D(const Cart2D< Y > &p)
Definition: CRNPixel.h:405
constexpr XYZ()
Definition: CRNPixel.h:476
A class containing informations on a type.
Definition: CRNType.h:176
constexpr Polar2D() noexcept
Definition: CRNPixel.h:401
constexpr HSV(uint8_t v_) noexcept
Definition: CRNPixel.h:185