Commit b77123ed authored by Laurent Belcour's avatar Laurent Belcour

Parsing of output parametrization of data and functions

Fitting of diffuse with cosine weighting
parent b5091114
...@@ -354,3 +354,52 @@ class product_function : public nonlinear_function ...@@ -354,3 +354,52 @@ class product_function : public nonlinear_function
nonlinear_function *f1, *f2; nonlinear_function *f1, *f2;
}; };
class cosine_function : public nonlinear_function
{
public:
// Set the input parametrization to CARTESIAN to reduce the number
// of transformations in a compound object.
cosine_function()
{
setParametrization(params::CARTESIAN);
setDimX(6);
}
// Overload the function operator
virtual vec operator()(const vec& x) const
{
return value(x);
}
virtual vec value(const vec& x) const
{
vec res(dimY());
for(int i=0; i<dimY(); ++i) { res[i] = ((x[2] > 0.0) ? x[2] : 0.0) * ((x[5] > 0.0) ? x[5] : 0.0); }
return res;
}
//! \brief Number of parameters to this non-linear function
virtual int nbParameters() const
{
return 0;
}
//! Get the vector of parameters for the function
vec parameters() const
{
vec res(1);
return res;
}
//! Update the vector of parameters for the function
void setParameters(const vec&)
{
}
//! Obtain the derivatives of the function with respect to the
//! parameters.
vec parametersJacobian(const vec&) const
{
vec jac(1);
return jac;
}
};
...@@ -24,6 +24,7 @@ std::map<params::input, const param_info> create_map() ...@@ -24,6 +24,7 @@ std::map<params::input, const param_info> create_map()
/* 2D Params */ /* 2D Params */
_map.insert(std::make_pair<params::input, const param_info>(params::RUSIN_TH_TD, param_info("RUSIN_TH_TD", 2, "Radialy symmetric Half angle parametrization"))); _map.insert(std::make_pair<params::input, const param_info>(params::RUSIN_TH_TD, param_info("RUSIN_TH_TD", 2, "Radialy symmetric Half angle parametrization")));
_map.insert(std::make_pair<params::input, const param_info>(params::ISOTROPIC_TV_PROJ_DPHI, param_info("ISOTROPIC_TV_PROJ_DPHI", 2, "Isoptropic projected phi parametrization without a light direction."))); _map.insert(std::make_pair<params::input, const param_info>(params::ISOTROPIC_TV_PROJ_DPHI, param_info("ISOTROPIC_TV_PROJ_DPHI", 2, "Isoptropic projected phi parametrization without a light direction.")));
_map.insert(std::make_pair<params::input, const param_info>(params::RETRO_TL_TVL_PROJ_DPHI, param_info("RETRO_TVL_PROJ_DPHI", 2, "Isoptropic projected phi parametrization around the retro direction.")));
/* 3D Params */ /* 3D Params */
_map.insert(std::make_pair<params::input, const param_info>(params::RUSIN_TH_TD_PD, param_info("RUSIN_TH_TD_PD", 3, "Isotropic Half angle parametrization"))); _map.insert(std::make_pair<params::input, const param_info>(params::RUSIN_TH_TD_PD, param_info("RUSIN_TH_TD_PD", 3, "Isotropic Half angle parametrization")));
...@@ -170,6 +171,25 @@ void params::to_cartesian(const double* invec, params::input intype, ...@@ -170,6 +171,25 @@ void params::to_cartesian(const double* invec, params::input intype,
outvec[3] = sin(invec[0]); outvec[3] = sin(invec[0]);
outvec[4] = 0.0; outvec[4] = 0.0;
outvec[5] = cos(invec[0]); outvec[5] = cos(invec[0]);
}
break;
case RETRO_TL_TVL_PROJ_DPHI:
{
const double theta = std::fabs(sqrt(invec[1]*invec[1] + invec[2]*invec[2]) - invec[0]);
if(theta > 0.0)
{
outvec[0] = (invec[1]/theta)*sin(theta);
outvec[1] = (invec[2]/theta)*sin(theta);
}
else
{
outvec[0] = 0.0;
outvec[1] = 0.0;
}
outvec[2] = cos(theta);
outvec[3] = sin(invec[0]);
outvec[4] = 0.0;
outvec[5] = cos(invec[0]);
} }
break; break;
...@@ -397,7 +417,7 @@ params::input params::parse_input(const std::string& txt) ...@@ -397,7 +417,7 @@ params::input params::parse_input(const std::string& txt)
{ {
if(txt.compare(it->second.name) == 0) if(txt.compare(it->second.name) == 0)
{ {
std::cout << "<<INFO>> parsed input parametrization " << it->second.name << std::endl; std::cout << "<<INFO>> parsed input parametrization " << it->second.name << " from name \"" << txt << "\"" << std::endl;
return it->first; return it->first;
} }
} }
...@@ -405,6 +425,34 @@ params::input params::parse_input(const std::string& txt) ...@@ -405,6 +425,34 @@ params::input params::parse_input(const std::string& txt)
std::cout << "<<INFO>> the input parametrization is UNKNOWN_INPUT" << std::endl; std::cout << "<<INFO>> the input parametrization is UNKNOWN_INPUT" << std::endl;
return params::UNKNOWN_INPUT; return params::UNKNOWN_INPUT;
} }
params::output params::parse_output(const std::string& txt)
{
if(txt == std::string("ENERGY"))
{
return params::ENERGY;
}
else if(txt == std::string("INV_STERADIAN"))
{
return params::INV_STERADIAN;
}
else if(txt == std::string("INV_STERADIAN_COSINE_FACTOR"))
{
return params::INV_STERADIAN_COSINE_FACTOR;
}
else if(txt == std::string("RGB_COLOR"))
{
return params::RGB_COLOR;
}
else if(txt == std::string("XYZ_COLOR"))
{
return params::XYZ_COLOR;
}
else
{
return params::UNKNOWN_OUTPUT;
}
}
std::string params::get_name(const params::input param) std::string params::get_name(const params::input param)
{ {
......
...@@ -52,10 +52,20 @@ class params ...@@ -52,10 +52,20 @@ class params
SCHLICK_TK_PK, /*!< Schlick's back vector parametrization */ SCHLICK_TK_PK, /*!< Schlick's back vector parametrization */
SCHLICK_VK, /*!< Schlick's back vector */ SCHLICK_VK, /*!< Schlick's back vector */
SCHLICK_TK_PROJ_DPHI, /*!< 2D Parametrization where the phi component is projected and
the parametrization is centered around the back direction.
\f$[x, y] = [\theta_K \cos(\phi_K), \theta_K \sin(\phi_K)]\f$*/
COS_TK, /*!< Schlick's back vector dot product with the normal */ COS_TK, /*!< Schlick's back vector dot product with the normal */
RETRO_TL_TVL_PROJ_DPHI,/*!< 2D Parametrization where the phi component is projected and
the parametrization is centered around the retro direction
\f$[x, y] = [\theta_{VL} \cos(\Delta\phi), \theta_{VL}
\sin(\Delta\phi)]\f$.*/
STEREOGRAPHIC, /*!< Stereographic projection of the Light and View vectors */ STEREOGRAPHIC, /*!< Stereographic projection of the Light and View vectors */
SPHERICAL_TL_PL_TV_PV, /*!< Light and View vectors represented in spherical coordinates */ SPHERICAL_TL_PL_TV_PV, /*!< Light and View vectors represented in spherical coordinates */
COS_TLV, /*!< Dot product between the Light and View vector */ COS_TLV, /*!< Dot product between the Light and View vector */
COS_TLR, /*!< Dot product between the Light and Reflected vector */ COS_TLR, /*!< Dot product between the Light and Reflected vector */
...@@ -70,7 +80,7 @@ class params ...@@ -70,7 +80,7 @@ class params
\theta_v \sin(\Delta\phi).\f$]*/ \theta_v \sin(\Delta\phi).\f$]*/
ISOTROPIC_TD_PD, /*!< Difference between two directions such as R and H */ ISOTROPIC_TD_PD, /*!< Difference between two directions such as R and H */
BARYCENTRIC_ALPHA_SIGMA, /*!< Barycentric parametrization defined in Stark et alL [2004]. BARYCENTRIC_ALPHA_SIGMA, /*!< Barycentric parametrization defined in Stark et al. [2004].
Coordinates are: \f$[\alpha, \sigma] = [{1\over 2}(1 - \vec{l}\vec{v}), Coordinates are: \f$[\alpha, \sigma] = [{1\over 2}(1 - \vec{l}\vec{v}),
(1-(\vec{h}.\vec{n})^2)(1 - \alpha)]\f$ */ (1-(\vec{h}.\vec{n})^2)(1 - \alpha)]\f$ */
...@@ -102,23 +112,13 @@ class params ...@@ -102,23 +112,13 @@ class params
//! \brief parse a string to provide a parametrization type. //! \brief parse a string to provide a parametrization type.
static params::input parse_input(const std::string& txt); static params::input parse_input(const std::string& txt);
//! \brief parse a string to provide a parametrization type.
static params::output parse_output(const std::string& txt);
//! \brief look for the string associated with a parametrization //! \brief look for the string associated with a parametrization
//! type. //! type.
static std::string get_name(const params::input param); static std::string get_name(const params::input param);
//! \brief parse a string to provide a parametrization type.
static params::output parse_output(const std::string& txt)
{
if(txt == std::string("ENERGY"))
{
return params::ENERGY;
}
else
{
return params::UNKNOWN_OUTPUT;
}
}
//! \brief static function for input type convertion. This //! \brief static function for input type convertion. This
//! function allocate the resulting vector. //! function allocate the resulting vector.
static double* convert(const double* invec, params::input intype, static double* convert(const double* invec, params::input intype,
...@@ -215,6 +215,25 @@ class params ...@@ -215,6 +215,25 @@ class params
} }
} }
//! \brief Is the value stored weighted by a cosine factor
static bool is_cosine_weighted(params::output t)
{
switch(t)
{
case params::INV_STERADIAN_COSINE_FACTOR:
return true;
break;
case params::INV_STERADIAN:
case params::ENERGY:
case params::RGB_COLOR:
case params::XYZ_COLOR:
default:
return false;
break;
}
}
//! \brief from the 4D definition of a half vector parametrization, //! \brief from the 4D definition of a half vector parametrization,
//! export the cartesian coordinates. //! export the cartesian coordinates.
static void half_to_cartesian(double theta_h, double phi_h, static void half_to_cartesian(double theta_h, double phi_h,
......
...@@ -374,7 +374,15 @@ function* plugins_manager::get_function(const arguments& args) ...@@ -374,7 +374,15 @@ function* plugins_manager::get_function(const arguments& args)
} }
} }
//*
// Correction of the data by 1/cosine(theta_L)
if(args.is_defined("data-correct-cosine"))
{
nonlinear_function* cosine = new cosine_function();
func = new product_function(cosine, dynamic_cast<nonlinear_function*>(func));
}
// End of correction
//*/
return func; return func;
} }
data* plugins_manager::get_data(const std::string& n) data* plugins_manager::get_data(const std::string& n)
......
...@@ -98,6 +98,7 @@ void vertical_segment::load(const std::string& filename, const arguments& args) ...@@ -98,6 +98,7 @@ void vertical_segment::load(const std::string& filename, const arguments& args)
linestream >> v[i] ; linestream >> v[i] ;
/*
// Correction of the data by 1/cosine(theta_L) // Correction of the data by 1/cosine(theta_L)
double factor = 1.0; double factor = 1.0;
if(args.is_defined("data-correct-cosine")) if(args.is_defined("data-correct-cosine"))
...@@ -107,11 +108,12 @@ void vertical_segment::load(const std::string& filename, const arguments& args) ...@@ -107,11 +108,12 @@ void vertical_segment::load(const std::string& filename, const arguments& args)
factor = 1.0/cart[5]; factor = 1.0/cart[5];
} }
// End of correction // End of correction
*/
for(int i=0; i<dimY(); ++i) for(int i=0; i<dimY(); ++i)
{ {
linestream >> v[dimX() + i]; linestream >> v[dimX() + i];
v[dimX() + i] /= factor; // v[dimX() + i] /= factor;
} }
// Check if the data containt a vertical segment around the mean // Check if the data containt a vertical segment around the mean
......
...@@ -29,7 +29,14 @@ vec abc_function::value(const vec& x) const ...@@ -29,7 +29,14 @@ vec abc_function::value(const vec& x) const
for(int i=0; i<dimY(); ++i) for(int i=0; i<dimY(); ++i)
{ {
res[i] = _a[i] / pow(1.0 + _b[i]*hn, _c[i]); if(hn > 0.0 && hn < 1.0)
{
res[i] = _a[i] / pow(1.0 + _b[i]*hn, _c[i]);
}
else
{
res[i] = 0.0;
}
} }
return res; return res;
} }
......
...@@ -162,15 +162,40 @@ vec diffuse_function::parametersJacobian(const vec& x) const ...@@ -162,15 +162,40 @@ vec diffuse_function::parametersJacobian(const vec& x) const
void diffuse_function::bootstrap(const data* d, const arguments& args) void diffuse_function::bootstrap(const data* d, const arguments& args)
{ {
// Set the diffuse component // Set the diffuse component
vec x0 = d->get(0); if(params::is_cosine_weighted(d->output_parametrization()))
for(int i=0; i<d->dimY(); ++i) {
_kd[i] = x0[d->dimX() + i]; vec cart(6);
for(int i=0; i<d->dimY(); ++i)
_kd[i] = std::numeric_limits<double>::max();
for(int i=1; i<d->size(); ++i)
{
vec x = d->get(i);
params::convert(&x[0], d->input_parametrization(), params::CARTESIAN, &cart[0]);
double cosine = (cart[2] > 0.0 ? cart[2] : 0.0) * (cart[5] > 0.0 ? cart[5] : 0.0);
for(int i=1; i<d->size(); ++i) if(cosine > 0.0)
{
for(int j=0; j<d->dimY(); ++j)
{
_kd[j] = std::min(x[d->dimX() + j] / cosine, _kd[j]);
}
}
}
}
else
{ {
vec xi = d->get(i); vec x0 = d->get(0);
for(int j=0; j<d->dimY(); ++j) for(int i=0; i<d->dimY(); ++i)
_kd[j] = std::min(xi[d->dimX() + j], _kd[j]); _kd[i] = x0[d->dimX() + i];
for(int i=1; i<d->size(); ++i)
{
vec xi = d->get(i);
for(int j=0; j<d->dimY(); ++j)
_kd[j] = std::min(xi[d->dimX() + j], _kd[j]);
}
} }
std::cout << "<<INFO>> found diffuse: " << _kd << std::endl; std::cout << "<<INFO>> found diffuse: " << _kd << std::endl;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment