libcrn  3.9.5
A document image processing library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CRNPixel.cpp
Go to the documentation of this file.
1 /* Copyright 2015 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.cpp
19  * \author Yann LEYDIER
20  */
21 
22 #include <CRNImage/CRNPixel.h>
23 
24 using namespace crn;
25 using namespace crn::pixel;
26 
27 XYZ::XYZ(const RGB8 &p)
28 {
29  static const auto xr = 0.4124;
30  static const auto xg = 0.3576;
31  static const auto xb = 0.1805;
32 
33  static const auto yr = 0.2126;
34  static const auto yg = 0.7152;
35  static const auto yb = 0.0722;
36 
37  static const auto zr = 0.0193;
38  static const auto zg = 0.1192;
39  static const auto zb = 0.9505;
40 
41  auto var_R = p.r / 255.0;
42  auto var_G = p.g / 255.0;
43  auto var_B = p.b / 255.0;
44 
45  if (var_R > 0.04045)
46  var_R = pow((var_R + 0.055) / 1.055, 2.4);
47  else
48  var_R /= 12.92;
49 
50  if (var_G > 0.04045)
51  var_G = pow((var_G + 0.055) / 1.055, 2.4);
52  else
53  var_G /= 12.92;
54 
55  if (var_B > 0.04045)
56  var_B = pow((var_B + 0.055) / 1.055, 2.4);
57  else
58  var_B /= 12.92;
59 
60  var_R *= 100;
61  var_G *= 100;
62  var_B *= 100;
63 
64  x = var_R * xr + var_G * xg + var_B * xb;
65  y = var_R * yr + var_G * yg + var_B * yb;
66  z = var_R * zr + var_G * zg + var_B * zb;
67 }
68 
69 YUV::YUV(const RGB8 &p)
70 {
71  y = 0.299 * p.r + 0.587 * p.g + 0.114 * p.b;
72  u = 0.492 * (p.b - y);
73  v = 0.877 * (p.r - y);
74 }
75 
76 XYZ::XYZ(const Lab &p)
77 {
78  auto var_Y = (p.l + 16) / 116.0;
79  auto var_X = p.a / 500.0 + var_Y;
80  auto var_Z = var_Y - p.b / 200.0;
81 
82  if (pow(var_Y, 3) > 0.008856)
83  var_Y = pow(var_Y, 3);
84  else
85  var_Y = (var_Y - 16 / 116.0) / 7.787;
86  if (pow(var_X, 3) > 0.008856)
87  var_X = pow(var_X, 3);
88  else
89  var_X = (var_X - 16 / 116.0) / 7.787;
90  if (pow(var_Z, 3) > 0.008856)
91  var_Z = pow(var_Z, 3);
92  else
93  var_Z = (var_Z - 16 / 116.0) / 7.787;
94 
95  x = var_X * 95.047;
96  y = var_Y * 100.000;
97  z = var_Z * 108.883;
98 }
99 
100 XYZ::XYZ(const Luv &p)
101 {
102  auto var_Y = (p.l + 16) / 116.0;
103  if (pow(var_Y, 3) > 0.008856)
104  var_Y = pow(var_Y, 3);
105  else
106  var_Y = (var_Y - 16 / 116.0) / 7.787;
107 
108  static const auto ref_X = 95.047; //Observer= 2°, Illuminant= D65
109  static const auto ref_Y = 100.000;
110  static const auto ref_Z = 108.883;
111  static const auto ref_U = ( 4 * ref_X ) / ( ref_X + ( 15 * ref_Y ) + ( 3 * ref_Z ) );
112  static const auto ref_V = ( 9 * ref_Y ) / ( ref_X + ( 15 * ref_Y ) + ( 3 * ref_Z ) );
113 
114  auto var_U = p.u / (13 * p.l) + ref_U;
115  auto var_V = p.v / (13 * p.l) + ref_V;
116 
117  y = var_Y * 100;
118  x = -( 9 * y * var_U ) / ( ( var_U - 4 ) * var_V - var_U * var_V );
119  z = ( 9 * y - ( 15 * var_V * y ) - ( var_V * x ) ) / ( 3 * var_V );
120 }
121 
122 Lab::Lab(const XYZ &p)
123 {
124  auto var_X = p.x / 95.047;
125  auto var_Y = p.y / 100.000;
126  auto var_Z = p.z / 108.883;
127 
128  if (var_X > 0.008856)
129  var_X = pow(var_X, 1/3.0);
130  else
131  var_X = (7.787 * var_X) + (16 / 116.0);
132  if (var_Y > 0.008856)
133  var_Y = pow(var_Y, 1/3.0);
134  else
135  var_Y = (7.787 * var_Y) + (16 / 116.0);
136  if (var_Z > 0.008856)
137  var_Z = pow(var_Z, 1/3.0);
138  else
139  var_Z = (7.787 * var_Z) + (16 / 116.0);
140 
141  l = (116 * var_Y) - 16;
142  a = 500 * (var_X - var_Y);
143  b = 200 * (var_Y - var_Z);
144 }
145 
146 Luv::Luv(const XYZ &p)
147 {
148  static const auto ref_X = 95.047; //Observer= 2°, Illuminant= D65
149  static const auto ref_Y = 100.000;
150  static const auto ref_Z = 108.883;
151  static const auto ref_U = ( 4 * ref_X ) / ( ref_X + ( 15 * ref_Y ) + ( 3 * ref_Z ) );
152  static const auto ref_V = ( 9 * ref_Y ) / ( ref_X + ( 15 * ref_Y ) + ( 3 * ref_Z ) );
153 
154  auto var_Y = p.y / 100.0;
155  if (var_Y > 0.008856 )
156  var_Y = pow(var_Y, 1.0 / 3.0);
157  else
158  var_Y = ( 7.787 * var_Y ) + 16.0 / 116.0;
159  l = 116.0 * var_Y - 16.0;
160 
161  auto denom = p.x + 15 * p.y + 3 * p.z;
162  if (denom != 0.0)
163  {
164  auto var_U = (4 * p.x) / denom;
165  auto var_V = (9 * p.y) / denom;
166  u= 13 * l * (var_U - ref_U);
167  v= 13 * l * (var_V - ref_V);
168  }
169  else
170  {
171  u = v = 0;
172  }
173 }
174 
constexpr Luv()
Definition: CRNPixel.h:647
constexpr Lab()
Definition: CRNPixel.h:597
constexpr YUV()
Definition: CRNPixel.h:529
constexpr XYZ()
Definition: CRNPixel.h:476