52 #ifndef __PCL_RGBColorSystem_h
53 #define __PCL_RGBColorSystem_h
63 #define _1_3 3.333333333333333e-01
64 #define _1_6 1.666666666666667e-01
65 #define _2_3 6.666666666666667e-01
66 #define _16_116 1.379310344827586e-01
67 #define CIEEpsilon 8.856451679035631e-03
68 #define CIEKappa 9.032962962962963e+02
69 #define CIEKappa116 7.787037037037037e+00
70 #define CIED501931XR 0.96422
71 #define CIED501931ZR 0.82521
72 #define CIED501964XR 0.96720
73 #define CIED501964ZR 0.81427
119 if ( m_data !=
nullptr )
122 m_data =
new Data( 2.2F,
true, sRGB_x, sRGB_y, sRGB_Y );
156 m_data =
new Data( gamma, issRGB, x, y, Y );
179 RGBColorSystem(
float gamma,
bool issRGB,
const float* x,
const float* y,
const float* Y =
nullptr )
189 if ( m_data !=
nullptr )
202 return m_data->IsUnique();
214 return m_data == s.m_data;
229 Data* newData =
new Data( *m_data );
245 return m_data->gamma;
253 return m_data->issRGB;
263 return m_data->isLinear;
416 return S1.
IsAliasOf( S2 ) || *S1.m_data == *S2.m_data;
429 rgbws.m_data->Attach();
431 m_data = rgbws.m_data;
455 XYZLab( R = m_data->CIEY( R, G, B ) );
456 return sample( (1.16 * R) - 0.16 );
460 sample Luminance( sample R, sample G, sample B )
const
462 return Lightness( R, G, B );
470 return Lightness( R, G, B );
486 K = Lightness( R, G, B );
544 H = 2 + (B - R)/delta;
546 H = 4 + (R - G)/delta;
572 return sample( (1.0 + max != 1.0) ? delta/max : 0.0 );
595 return delta/((sum <= 1) ? sum : 2-sum);
610 return HSVSaturation( R, G, B );
641 H = 2 + (B - R)/delta;
643 H = 4 + (R - G)/delta;
687 S = delta/((sum <= 1) ? sum : 2-sum);
692 H = 2 + (B - R)/delta;
694 H = 4 + (R - G)/delta;
727 RGBToHSV( H, S, V, R, G, B );
728 L = Lightness( R, G, B );
753 RGBToHSI( H, S, I, R, G, B );
754 L = Lightness( R, G, B );
767 m_data->RGBToCIEXYZ( X, Y, Z, R, G, B );
784 m_data->RGBToCIEXZ( X, Z, R, G, B );
794 return m_data->CIEX( R, G, B );
804 return m_data->CIEY( R, G, B );
814 return m_data->CIEZ( R, G, B );
825 return 1.16*Y - 0.16;
851 m_data->RGBToCIEXYZ( X, Y, Z, R, G, B );
852 XYZLab( X ); XYZLab( Y ); XYZLab( Z );
853 L = m_data->Range(
sample( (1.16 * Y) - 0.16 ) );
854 a = m_data->Range( (5*(X - Y) + m_data->zA)/m_data->mA );
855 b = m_data->Range( (2*(Y - Z) + m_data->zB)/m_data->mB );
870 m_data->RGBToCIEXYZ( X, Y, Z, R, G, B );
871 XYZLab( X ); XYZLab( Y ); XYZLab( Z );
872 a = m_data->Range( (5*(X - Y) + m_data->zA)/m_data->mA );
873 b = m_data->Range( (2*(Y - Z) + m_data->zB)/m_data->mB );
885 m_data->RGBToCIEXY( X, Y, R, G, B );
886 XYZLab( X ); XYZLab( Y );
887 return m_data->Range( (5*(X - Y) + m_data->zA)/m_data->mA );
902 m_data->RGBToCIEYZ( Y, Z, R, G, B );
903 XYZLab( Y ); XYZLab( Z );
904 return m_data->Range( (2*(Y - Z) + m_data->zB)/m_data->mB );
919 m_data->RGBToCIEXYZ( X, Y, Z, R, G, B );
920 XYZLab( X ); XYZLab( Y ); XYZLab( Z );
923 return m_data->Range(
pcl::Sqrt( a*a + b*b )/m_data->mC );
959 m_data->RGBToCIEXYZ( X, Y, Z, R, G, B );
960 XYZLab( X ); XYZLab( Y ); XYZLab( Z );
978 m_data->RGBToCIEXYZ( X, Y, Z, R, G, B );
979 XYZLab( X ); XYZLab( Y ); XYZLab( Z );
980 L = m_data->Range(
sample( (1.16 * Y) - 0.16 ) );
983 c = m_data->Range(
pcl::Sqrt( a*a + b*b )/m_data->mC );
1009 m_data->RGBToCIEXYZ( X, Y, Z, R, G, B );
1010 XYZLab( X ); XYZLab( Y ); XYZLab( Z );
1011 L = m_data->Range(
sample( (1.16 * Y) - 0.16 ) );
1012 a = m_data->Range( ((X = 5*(X - Y)) + m_data->zA)/m_data->mA );
1013 b = m_data->Range( ((Z = 2*(Y - Z)) + m_data->zB)/m_data->mB );
1014 c = m_data->Range(
pcl::Sqrt( X*X + Z*Z )/m_data->mC );
1042 sample t = V*(1 - S*(1 - f));
1046 case 0: R = V; G = t; B = p;
break;
1047 case 1: R = q; G = V; B = p;
break;
1048 case 2: R = p; G = V; B = t;
break;
1049 case 3: R = p; G = q; B = V;
break;
1050 case 4: R = t; G = p; B = V;
break;
1051 case 5: R = V; G = p; B = q;
break;
1052 default: R = G = B = V;
break;
1089 HSVToRGB( R, G, B, H, S, V );
1092 RGBToCIEab( a, b, R, G, B );
1093 CIELabToRGB( R, G, B, L, a, b );
1120 sample v2 = (I < 0.5) ? I*(1 + S) : I + S - S*I;
1122 R = HSIH2RGB( v1, v2, H+_1_3 );
1123 G = HSIH2RGB( v1, v2, H );
1124 B = HSIH2RGB( v1, v2, H-_1_3 );
1163 HSIToRGB( R, G, B, H, S, I );
1166 RGBToCIEab( a, b, R, G, B );
1167 CIELabToRGB( R, G, B, L, a, b );
1182 m_data->CIEXYZToRGB( R, G, B, X, Y, Z );
1195 XYZLab( X ); XYZLab( Y ); XYZLab( Z );
1196 L = m_data->Range(
sample( (1.16 * Y) - 0.16 ) );
1197 a = m_data->Range( (5*(X - Y) + m_data->zA)/m_data->mA );
1198 b = m_data->Range( (2*(Y - Z) + m_data->zB)/m_data->mB );
1212 sample X = (m_data->mA*a - m_data->zA)/5 + Y;
1213 sample Z = Y - (m_data->mB*b - m_data->zB)/2;
1214 LabXYZ( X ); LabXYZ( Y ); LabXYZ( Z );
1215 m_data->CIEXYZToRGB( R, G, B, X, Y, Z );
1228 Y =
sample( (L + 0.16)/1.16 );
1229 X = (m_data->mA*a - m_data->zA)/5 + Y;
1230 Z = Y - (m_data->mB*b - m_data->zB)/2;
1231 LabXYZ( X ); LabXYZ( Y ); LabXYZ( Z );
1232 X = m_data->Range( X );
1233 Y = m_data->Range( Y );
1234 Z = m_data->Range( Z );
1251 L = m_data->Range( L0 );
1252 a = m_data->mA*a - m_data->zA;
1253 b = m_data->mB*b - m_data->zB;
1254 c = m_data->Range(
Sqrt( a*a + b*b )/m_data->mC );
1278 LabXYZ( X ); LabXYZ( Y ); LabXYZ( Z );
1279 m_data->CIEXYZToRGB( R, G, B, X, Y, Z );
1296 L = m_data->Range( L0 );
1299 a = m_data->Range( (c*a + m_data->zA)/m_data->mA );
1300 b = m_data->Range( (c*b + m_data->zB)/m_data->mB );
1310 PCL_PRECONDITION( x >= 0 && x <= 1 )
1311 return (x > 0.04045) ?
Pow( (x + 0.055)/1.055, 2.4 ) : x/12.92;
1321 PCL_PRECONDITION( x >= 0 && x <= 1 )
1322 return (x > 0.0031308) ? 1.055*
Pow( x,
sample( 1/2.4 ) ) - 0.055 : 12.92*x;
1329 float gamma, gammaInv;
1361 Data(
float,
bool,
const float*,
const float*,
const float* );
1362 Data(
const Data& ) =
default;
1366 bool operator ==(
const RGBColorSystem::Data& data )
const
1368 return gamma == data.gamma &&
1369 issRGB == data.issRGB &&
1371 x == data.x && y == data.y;
1378 void LinearRGB( sample& x )
const
1380 x = sample( issRGB ? SRGBToLinear(
double( x ) ) :
Pow(
double( x ),
double( gamma ) ) );
1383 void GammaRGB( sample& x )
const
1385 x = sample( issRGB ? LinearToSRGB(
double( x ) ) :
Pow(
double( x ),
double( gammaInv ) ) );
1392 void RGBToCIEXYZ( sample& X, sample& Y, sample& Z, sample R, sample G, sample B )
const
1401 X =
Range( (R*M[0] + G*M[1] + B*M[2])/mX );
1402 Y =
Range( R*M[3] + G*M[4] + B*M[5] );
1403 Z =
Range( (R*M[6] + G*M[7] + B*M[8])/mZ );
1406 void CIEXYZToRGB( sample& R, sample& G, sample& B, sample X, sample Y, sample Z )
const
1410 R =
Range( X*M_[0] + Y*M_[1] + Z*M_[2] );
1411 G =
Range( X*M_[3] + Y*M_[4] + Z*M_[5] );
1412 B =
Range( X*M_[6] + Y*M_[7] + Z*M_[8] );
1426 sample CIEX( sample R, sample G, sample B )
const
1435 return Range( (R*M[0] + G*M[1] + B*M[2])/mX );
1438 sample CIEY( sample R, sample G, sample B )
const
1447 return Range( R*M[3] + G*M[4] + B*M[5] );
1450 sample CIEZ( sample R, sample G, sample B )
const
1459 return Range( (R*M[6] + G*M[7] + B*M[8])/mZ );
1462 void RGBToCIEXY( sample& X, sample& Y, sample R, sample G, sample B )
const
1471 X =
Range( (R*M[0] + G*M[1] + B*M[2])/mX );
1472 Y =
Range( R*M[3] + G*M[4] + B*M[5] );
1475 void RGBToCIEYZ( sample& Y, sample& Z, sample R, sample G, sample B )
const
1484 Y =
Range( R*M[3] + G*M[4] + B*M[5] );
1485 Z =
Range( (R*M[6] + G*M[7] + B*M[8])/mZ );
1488 void RGBToCIEXZ( sample& X, sample& Z, sample R, sample G, sample B )
const
1497 X =
Range( (R*M[0] + G*M[1] + B*M[2])/mX );
1498 Z =
Range( (R*M[6] + G*M[7] + B*M[8])/mZ );
1504 static sample
Range(
const sample& x )
1506 return pcl::Range( x, sample( 0 ), sample( 1 ) );
1510 Data* m_data =
nullptr;
1512 void DetachFromData()
1514 if ( !m_data->Detach() )
1521 static void XYZLab( sample& x )
1523 x = (x > CIEEpsilon) ?
Pow( x, sample( _1_3 ) ) : sample( CIEKappa116*x + _16_116 );
1529 static void LabXYZ( sample& x )
1532 x = (x3 > CIEEpsilon) ? x3 : sample( (x - _16_116)/CIEKappa116 );
1538 static sample HSIH2RGB( sample v1, sample v2, sample H )
1546 return v1 + 6*H*(v2 - v1);
1552 return v1 + 6*(_2_3 - H)*(v2 - v1);
1564 static const float sRGB_x[ 3 ];
1569 static const float sRGB_y[ 3 ];
1574 static const float sRGB_Y[ 3 ];
1581 #ifdef __PCL_WITH_STANDARD_RGB_WORKING_SPACES
1586 static const float AdobeRGB1998_x[ 3 ];
1587 static const float AdobeRGB1998_y[ 3 ];
1588 static const float AdobeRGB1998_Y[ 3 ];
1593 static const float AppleRGB_x[ 3 ];
1594 static const float AppleRGB_y[ 3 ];
1595 static const float AppleRGB_Y[ 3 ];
1600 static const float BestRGB_x[ 3 ];
1601 static const float BestRGB_y[ 3 ];
1602 static const float BestRGB_Y[ 3 ];
1607 static const float BetaRGB_x[ 3 ];
1608 static const float BetaRGB_y[ 3 ];
1609 static const float BetaRGB_Y[ 3 ];
1614 static const float BruceRGB_x[ 3 ];
1615 static const float BruceRGB_y[ 3 ];
1616 static const float BruceRGB_Y[ 3 ];
1621 static const float CIERGB_x[ 3 ];
1622 static const float CIERGB_y[ 3 ];
1623 static const float CIERGB_Y[ 3 ];
1628 static const float ColorMatchRGB_x[ 3 ];
1629 static const float ColorMatchRGB_y[ 3 ];
1630 static const float ColorMatchRGB_Y[ 3 ];
1635 static const float NTSCRGB_x[ 3 ];
1636 static const float NTSCRGB_y[ 3 ];
1637 static const float NTSCRGB_Y[ 3 ];
1642 static const float PALSECAMRGB_x[ 3 ];
1643 static const float PALSECAMRGB_y[ 3 ];
1644 static const float PALSECAMRGB_Y[ 3 ];
1649 static const float ProPhotoRGB_x[ 3 ];
1650 static const float ProPhotoRGB_y[ 3 ];
1651 static const float ProPhotoRGB_Y[ 3 ];
1656 static const float SMPTECRGB_x[ 3 ];
1657 static const float SMPTECRGB_y[ 3 ];
1658 static const float SMPTECRGB_Y[ 3 ];
1663 static const float WideGamutRGB_x[ 3 ];
1664 static const float WideGamutRGB_y[ 3 ];
1665 static const float WideGamutRGB_Y[ 3 ];
Fundamental numeric constants.
static constexpr T _2pi()
32-bit floating point real vector.
Generic vector of arbitrary length.
Colorimetrically defined RGB working color space.
sample CIEa(sample R, sample G, sample B) const
RGBColorSystem(float gamma, bool issRGB, const float *x, const float *y, const float *Y=nullptr)
sample Hue(sample R, sample G, sample B) const
static const RGBColorSystem sRGB
static double LinearToSRGB(double x)
sample HSISaturation(sample R, sample G, sample B) const
void CIEXYZToCIELab(sample &L, sample &a, sample &b, sample X, sample Y, sample Z) const
void RGBToHSIL(sample &H, sample &S, sample &I, sample &L, sample R, sample G, sample B) const
sample CIEb(sample R, sample G, sample B) const
double CIEXNormalizationFactor() const
const FVector & LuminanceCoefficients() const
sample Intensity(sample R, sample G, sample B) const
sample HSVSaturation(sample R, sample G, sample B) const
const FVector & ChromaticityXCoordinates() const
sample CIEYToCIEL(sample Y) const
const Vector & XYZToRGBMatrix() const
sample Lightness(sample R, sample G, sample B) const
double CIEaNormalizationFactor() const
const Vector & RGBToXYZMatrix() const
sample CIEL(sample R, sample G, sample B) const
void HSVLToRGB(sample &R, sample &G, sample &B, sample H, sample S, sample V, sample L) const
sample CIEhr(sample R, sample G, sample B) const
RGBColorSystem(float gamma, bool issRGB, const FVector &x, const FVector &y, const FVector &Y=FVector())
sample Value(sample R, sample G, sample B) const
double CIEZNormalizationFactor() const
sample CIEX(sample R, sample G, sample B) const
void CIELchToRGB(sample &R, sample &G, sample &B, sample L, sample c, sample h) const
void RGBToGray(sample &K, sample R, sample G, sample B) const
sample CIEY(sample R, sample G, sample B) const
void CIELabToCIEXYZ(sample &X, sample &Y, sample &Z, sample L, sample a, sample b) const
double CIEbNormalizationOffset() const
void CIELabToRGB(sample &R, sample &G, sample &B, sample L, sample a, sample b) const
static void RGBToHSI(sample &H, sample &S, sample &I, sample R, sample G, sample B)
void CIEXYZToRGB(sample &R, sample &G, sample &B, sample X, sample Y, sample Z) const
static void RGBToHSV(sample &H, sample &S, sample &V, sample R, sample G, sample B)
void RGBToCIEXZ(sample &X, sample &Z, sample R, sample G, sample B) const
bool IsAliasOf(const RGBColorSystem &s) const
const FVector & ChromaticityYCoordinates() const
sample CIEZ(sample R, sample G, sample B) const
double CIEaNormalizationOffset() const
static void HSIToRGB(sample &R, sample &G, sample &B, sample H, sample S, sample I)
sample CIEh(sample R, sample G, sample B) const
RGBColorSystem(const RGBColorSystem &s)
void RGBToCIELab(sample &L, sample &a, sample &b, sample R, sample G, sample B) const
void CIELchToCIELab(sample &L, sample &a, sample &b, sample L0, sample c, sample h) const
sample Saturation(sample R, sample G, sample B) const
void HSILToRGB(sample &R, sample &G, sample &B, sample H, sample S, sample I, sample L) const
sample CIEc(sample R, sample G, sample B) const
void RGBToCIELch(sample &L, sample &c, sample &h, sample R, sample G, sample B) const
virtual ~RGBColorSystem()
static void HSVToRGB(sample &R, sample &G, sample &B, sample H, sample S, sample V)
void RGBToCIEXYZ(sample &X, sample &Y, sample &Z, sample R, sample G, sample B) const
void RGBToCIEab(sample &a, sample &b, sample R, sample G, sample B) const
void RGBToCIELabc(sample &L, sample &a, sample &b, sample &c, sample R, sample G, sample B) const
double CIEbNormalizationFactor() const
sample CIELToCIEY(sample L) const
static double SRGBToLinear(double x)
void CIELabToCIELch(sample &L, sample &c, sample &h, sample L0, sample a, sample b) const
void RGBToHSVL(sample &H, sample &S, sample &V, sample &L, sample R, sample G, sample B) const
double CIEcNormalizationFactor() const
void Assign(const RGBColorSystem &rgbws)
Thread-safe reference counter for copy-on-write data structures.
bool operator==(const Array< T, A > &x1, const Array< T, A > &x2) noexcept
Complex< T1 > Pow(const Complex< T1 > &c, T2 x) noexcept
Complex< T > Sqrt(const Complex< T > &c) noexcept
void SinCos(T x, T &sx, T &cx) noexcept
constexpr T ArcTan(T x) noexcept
int TruncInt(T x) noexcept
constexpr T Floor(T x) noexcept
constexpr const T & Min(const T &a, const T &b) noexcept
constexpr const T & Range(const T &x, const T &a, const T &b) noexcept
constexpr const T & Max(const T &a, const T &b) noexcept