Reduce or eliminate some artifacts in CIECAM02 - and others bugs
This commit is contained in:
@@ -25,6 +25,8 @@
|
||||
#include "imagefloat.h"
|
||||
#include "labimage.h"
|
||||
#define MAXR(a,b) ((a) > (b) ? (a) : (b))
|
||||
#define pow_F(a,b) (exp(b*log(a)))
|
||||
|
||||
|
||||
namespace rtengine {
|
||||
|
||||
@@ -66,6 +68,9 @@ class ColorTemp {
|
||||
static double d_factor( double f, double la ) {
|
||||
return f * (1.0 - ((1.0 / 3.6) * exp((-la - 42.0) / 92.0)));
|
||||
}
|
||||
static float d_factorfloat( float f, float la ) {
|
||||
return f * (1.0f - ((1.0f / 3.6f) * exp((-la - 42.0f) / 92.0f)));
|
||||
}
|
||||
|
||||
static double calculate_fl_from_la_ciecam02( double la ) {
|
||||
double la5 = la * 5.0;
|
||||
@@ -77,6 +82,16 @@ class ColorTemp {
|
||||
|
||||
return (0.2 * k * la5) + (0.1 * (1.0 - k) * (1.0 - k) * pow(la5, 1.0 / 3.0));
|
||||
}
|
||||
static float calculate_fl_from_la_ciecam02float( float la ) {
|
||||
float la5 = la * 5.0f;
|
||||
float k = 1.0f / (la5 + 1.0f);
|
||||
|
||||
/* Calculate k^4. */
|
||||
k = k * k;
|
||||
k = k * k;
|
||||
|
||||
return (0.2f * k * la5) + (0.1f * (1.0f - k) * (1.0f - k) * pow_F(la5, 1.0f / 3.0f));
|
||||
}
|
||||
|
||||
static double achromatic_response_to_white( double x, double y, double z, double d, double fl, double nbb, int gamu ) {
|
||||
double r, g, b;
|
||||
@@ -103,25 +118,76 @@ class ColorTemp {
|
||||
|
||||
return ((2.0 * rpa) + gpa + ((1.0 / 20.0) * bpa) - 0.305) * nbb;
|
||||
}
|
||||
|
||||
static float achromatic_response_to_whitefloat( float x, float y, float z, float d, float fl, float nbb, int gamu ) {
|
||||
float r, g, b;
|
||||
float rc, gc, bc;
|
||||
float rp, gp, bp;
|
||||
float rpa, gpa, bpa;
|
||||
gamu=1;
|
||||
xyz_to_cat02float( r, g, b, x, y, z, gamu );
|
||||
|
||||
rc = r * (((y * d) / r) + (1.0f - d));
|
||||
gc = g * (((y * d) / g) + (1.0f - d));
|
||||
bc = b * (((y * d) / b) + (1.0f - d));
|
||||
|
||||
cat02_to_hpefloat( rp, gp, bp, rc, gc, bc, gamu );
|
||||
if(gamu==1){//gamut correction M.H.Brill S.Susstrunk
|
||||
rp=MAXR(rp,0.0f);
|
||||
gp=MAXR(gp,0.0f);
|
||||
bp=MAXR(bp,0.0f);
|
||||
}
|
||||
|
||||
rpa = nonlinear_adaptationfloat( rp, fl );
|
||||
gpa = nonlinear_adaptationfloat( gp, fl );
|
||||
bpa = nonlinear_adaptationfloat( bp, fl );
|
||||
|
||||
return ((2.0f * rpa) + gpa + ((1.0f / 20.0f) * bpa) - 0.305f) * nbb;
|
||||
}
|
||||
|
||||
static void xyz_to_cat02 ( double &r, double &g, double &b, double x, double y, double z, int gamu );
|
||||
static void cat02_to_hpe ( double &rh, double &gh, double &bh, double r, double g, double b, int gamu );
|
||||
static void cat02_to_xyz ( double &x, double &y, double &z, double r, double g, double b, int gamu );
|
||||
static void hpe_to_xyz ( double &x, double &y, double &z, double r, double g, double b );
|
||||
|
||||
static void xyz_to_cat02float ( float &r, float &g, float &b, float x, float y, float z, int gamu );
|
||||
static void cat02_to_hpefloat ( float &rh, float &gh, float &bh, float r, float g, float b, int gamu );
|
||||
static void cat02_to_xyzfloat ( float &x, float &y, float &z, float r, float g, float b, int gamu );
|
||||
static void hpe_to_xyzfloat ( float &x, float &y, float &z, float r, float g, float b );
|
||||
|
||||
static void Aab_to_rgb( double &r, double &g, double &b, double A, double aa, double bb, double nbb );
|
||||
static void Aab_to_rgbfloat( float &r, float &g, float &b, float A, float aa, float bb, float nbb );
|
||||
static void calculate_ab( double &aa, double &bb, double h, double e, double t, double nbb, double a );
|
||||
static void calculate_abfloat( float &aa, float &bb, float h, float e, float t, float nbb, float a );
|
||||
|
||||
|
||||
static double nonlinear_adaptation( double c, double fl ) {
|
||||
double p;
|
||||
if(c<0.0){ p = pow( (-1.0*fl * c) / 100.0, 0.42 );return ((-1.0*400.0 * p) / (27.13 + p)) + 0.1;}
|
||||
else {p = pow( (fl * c) / 100.0, 0.42 ); return ((400.0 * p) / (27.13 + p)) + 0.1;}
|
||||
}
|
||||
static float nonlinear_adaptationfloat( float c, float fl ) {
|
||||
float p;
|
||||
if(c<0.0f){ p = pow_F( (-1.0f*fl * c) / 100.0f, 0.42f );return ((-1.0f*400.0f * p) / (27.13f + p)) + 0.1f;}
|
||||
else {p = pow_F( (fl * c) / 100.0f, 0.42f ); return ((400.0f * p) / (27.13f + p)) + 0.1f;}
|
||||
}
|
||||
|
||||
static double inverse_nonlinear_adaptation( double c, double fl ) {
|
||||
int c1;
|
||||
if(c-0.1 < 0.0) c1=-1; else c1=1;
|
||||
return c1*(100.0 / fl) * pow( (27.13 * fabs( c - 0.1 )) / (400.0 - fabs( c - 0.1 )), 1.0 / 0.42 );
|
||||
}
|
||||
static float inverse_nonlinear_adaptationfloat( float c, float fl ) {
|
||||
int c1;
|
||||
if(c-0.1f < 0.0f) c1=-1; else c1=1;
|
||||
return c1*(100.0f / fl) * pow_F( (27.13f * fabs( c - 0.1f )) / (400.0f - fabs( c - 0.1f )), 1.0f / 0.42f );
|
||||
}
|
||||
|
||||
|
||||
static void curvecolor(double satind, double satval, double &sres, double parsat);
|
||||
static void curvecolorfloat(float satind, float satval, float &sres, float parsat);
|
||||
static void curveJ (double br, double contr, int db, LUTf & outCurve , LUTu & histogram ) ;
|
||||
static void curveJfloat (float br, float contr, int db, LUTf & outCurve , LUTu & histogram ) ;
|
||||
|
||||
bool operator== (const ColorTemp& other) { return fabs(temp-other.temp)<1e-10 && fabs(green-other.green)<1e-10; }
|
||||
bool operator!= (const ColorTemp& other) { return !(*this==other); }
|
||||
@@ -234,6 +300,13 @@ class ColorTemp {
|
||||
double xw, double yw, double zw,
|
||||
double yb, double la,
|
||||
double f, double c, double nc, bool doneinit2, int gamu );
|
||||
|
||||
static void jch2xyz_ciecam02float( float &x, float &y, float &z,
|
||||
float J, float C, float h,
|
||||
float xw, float yw, float zw,
|
||||
float yb, float la,
|
||||
float f, float c, float nc, bool doneinit2, int gamu );
|
||||
|
||||
/**
|
||||
* Forward transform from XYZ to CIECAM02 JCh.
|
||||
*/
|
||||
@@ -244,69 +317,14 @@ class ColorTemp {
|
||||
double yb, double la,
|
||||
double f, double c, double nc, double pilotd, bool doneinit1, int gamu );
|
||||
|
||||
static void xyz2jchqms_ciecam02float( float &J, float &C, float &h,
|
||||
float &Q, float &M, float &s,float &aw, float &fl, float &wh,
|
||||
float x, float y, float z,
|
||||
float xw, float yw, float zw,
|
||||
float yb, float la,
|
||||
float f, float c, float nc, float pilotd, bool doneinit1, int gamu );
|
||||
|
||||
|
||||
};
|
||||
inline void ColorTemp::xyz_to_cat02( double &r, double &g, double &b, double x, double y, double z, int gamu )
|
||||
{
|
||||
gamu=1;
|
||||
if(gamu==0){
|
||||
r = ( 0.7328 * x) + (0.4296 * y) - (0.1624 * z);
|
||||
g = (-0.7036 * x) + (1.6975 * y) + (0.0061 * z);
|
||||
b = ( 0.0030 * x) + (0.0136 * y) + (0.9834 * z);
|
||||
}
|
||||
else if (gamu==1) {//gamut correction M.H.Brill S.Susstrunk
|
||||
//r = ( 0.7328 * x) + (0.4296 * y) - (0.1624 * z);
|
||||
//g = (-0.7036 * x) + (1.6975 * y) + (0.0061 * z);
|
||||
//b = ( 0.0000 * x) + (0.0000 * y) + (1.0000 * z);
|
||||
r = ( 1.007245 * x) + (0.011136* y) - (0.018381 * z);//Changjun Li
|
||||
g = (-0.318061 * x) + (1.314589 * y) + (0.003471 * z);
|
||||
b = ( 0.0000 * x) + (0.0000 * y) + (1.0000 * z);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
inline void ColorTemp::cat02_to_xyz( double &x, double &y, double &z, double r, double g, double b, int gamu )
|
||||
{
|
||||
gamu=1;
|
||||
if(gamu==0) {
|
||||
x = ( 1.096124 * r) - (0.278869 * g) + (0.182745 * b);
|
||||
y = ( 0.454369 * r) + (0.473533 * g) + (0.072098 * b);
|
||||
z = (-0.009628 * r) - (0.005698 * g) + (1.015326 * b);
|
||||
}
|
||||
else if(gamu==1) {//gamut correction M.H.Brill S.Susstrunk
|
||||
//x = ( 1.0978566 * r) - (0.277843 * g) + (0.179987 * b);
|
||||
//y = ( 0.455053 * r) + (0.473938 * g) + (0.0710096* b);
|
||||
//z = ( 0.000000 * r) - (0.000000 * g) + (1.000000 * b);
|
||||
x = ( 0.99015849 * r) - (0.00838772* g) + (0.018229217 * b);//Changjun Li
|
||||
y = ( 0.239565979 * r) + (0.758664642 * g) + (0.001770137* b);
|
||||
z = ( 0.000000 * r) - (0.000000 * g) + (1.000000 * b);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
inline void ColorTemp::hpe_to_xyz( double &x, double &y, double &z, double r, double g, double b )
|
||||
{
|
||||
x = (1.910197 * r) - (1.112124 * g) + (0.201908 * b);
|
||||
y = (0.370950 * r) + (0.629054 * g) - (0.000008 * b);
|
||||
z = b;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline void ColorTemp::cat02_to_hpe( double &rh, double &gh, double &bh, double r, double g, double b, int gamu )
|
||||
{ gamu=1;
|
||||
if(gamu==0){
|
||||
rh = ( 0.7409792 * r) + (0.2180250 * g) + (0.0410058 * b);
|
||||
gh = ( 0.2853532 * r) + (0.6242014 * g) + (0.0904454 * b);
|
||||
bh = (-0.0096280 * r) - (0.0056980 * g) + (1.0153260 * b);
|
||||
}
|
||||
else if (gamu==1) {//Changjun Li
|
||||
rh = ( 0.550930835 * r) + (0.519435987* g) - ( 0.070356303* b);
|
||||
gh = ( 0.055954056 * r) + (0.89973132 * g) + (0.044315524 * b);
|
||||
bh = (0.0 * r) - (0.0* g) + (1.0 * b);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user