Commit 094bda71 authored by Laurent Belcour's avatar Laurent Belcour

Working with cosine weighted data. Still a rough version but manage to get results.

parent 0da3928c
......@@ -123,7 +123,7 @@ class params
//! type.
//! \todo Finish this implementation. It requires another static
//! object.
static std::string get_name(const params::output param)
static std::string get_name(const params::output)
{
return std::string("UNKNOWN_OUTPUT");
}
......
......@@ -205,7 +205,7 @@ function* plugins_manager::get_function(const std::string& filename)
if(!file.is_open())
{
std::cerr << "<<ERROR>> unable to open file \"" << filename << "\"" << std::endl ;
throw ;
return NULL;
}
// Set the precision of the input
......
......@@ -20,7 +20,7 @@ ALTA_DLL_EXPORT fitter* provide_fitter()
class CeresFunctor : public ceres::CostFunction
{
public:
CeresFunctor(nonlinear_function* f, const vec xi) : _f(f), _xi(xi)
CeresFunctor(nonlinear_function* f, const vec& xi, bool cos_fit = false) : _f(f), _xi(xi), _cos_fit(cos_fit)
{
set_num_residuals(f->dimY());
mutable_parameter_block_sizes()->push_back(f->nbParameters());
......@@ -52,6 +52,13 @@ class CeresFunctor : public ceres::CostFunction
}
// Should add the resulting vector completely
double costerm = 1.0;
if(_cos_fit)
{
double _x[6];
params::convert(&_xi[0], _f->input_parametrization(), params::CARTESIAN, _x);
costerm = _x[5]*_x[2];
}
vec _y = _di - _f->value(_xi);
for(int i=0; i<_f->dimY(); ++i)
{
......@@ -88,6 +95,7 @@ class CeresFunctor : public ceres::CostFunction
protected:
bool _cos_fit;
const vec _xi;
nonlinear_function* _f;
};
......@@ -116,6 +124,8 @@ bool nonlinear_fitter_ceres::fit_data(const data* d, function* fit, const argume
}
nonlinear_function* nf = dynamic_cast<nonlinear_function*>(fit);
// Should I include the cosine term during the fit ?
const bool cos_fit = args.is_defined("cos-fit");
#ifndef DEBUG
std::cout << "<<DEBUG>> number of parameters: " << nf->nbParameters() << std::endl;
......@@ -124,97 +134,37 @@ bool nonlinear_fitter_ceres::fit_data(const data* d, function* fit, const argume
{
return true;
}
#ifdef FIT_CHANNELS
if(args.is_defined("ceres-channels"))
{
std::cout << "<<WARNING>> will fit the output dimensions separately" << std::endl;
std::cout << "<<WARNING>> make sur the function is separable." << std::endl;
return fit_channel(d, nf, args);
}
else
#endif
{
/* Bootstrap the function */
nf->bootstrap(d, args);
/* the following starting values provide a rough fit. */
vec p = nf->parameters();
std::cout << "<<DEBUG>> Starting vector: " << p << std::endl;
std::cout << "<<DEBUG>> Final vector should be between " << nf->getParametersMin() << " and " << nf->getParametersMax() << std::endl;
// Create the problem
ceres::Problem problem;
for(int i=0; i<d->size(); ++i)
{
vec xi = d->get(i);
problem.AddResidualBlock(new CeresFunctor(nf, xi), NULL, &p[0]);
}
// Solves the NL problem
ceres::Solver::Summary summary;
ceres::Solve(options, &problem, &summary);
/* Bootstrap the function */
nf->bootstrap(d, args);
/* the following starting values provide a rough fit. */
vec p = nf->parameters();
#ifdef DEBUG
std::cout << summary.BriefReport() << std::endl;
#endif
std::cout << "<<INFO>> found parameters: " << p << std::endl;
nf->setParameters(p);
return true;
}
}
#ifdef FIT_CHANNELS
bool nonlinear_fitter_ceres::fit_channel(const data* d, nonlinear_function* nf,
const arguments& args)
{
/* the following starting values provide a rough fit. */
vec p = nf->parameters();
std::cout << "<<DEBUG>> Starting vector: " << p << std::endl;
std::cout << "<<DEBUG>> Final vector should be between " << nf->getParametersMin() << " and " << nf->getParametersMax() << std::endl;
// Convert the current function to monochromatic
nf->setDimY(1);
for(int c=0; c<d->dimY(); ++c)
{
nf->bootstrap(d, args);
// Temp parameter vector
vec temp_p = nf->parameters();
// Create the problem
ceres::Problem problem;
for(int i=0; i<d->size(); ++i)
{
vec xi = d->get(i);
problem.AddResidualBlock(new CeresFunctor(nf, xi, cos_fit), NULL, &p[0]);
}
// Create the problem
ceres::Problem problem;
for(int i=0; i<d->size(); ++i)
{
vec xi = d->get(i);
problem.AddResidualBlock(new ColorChannelCost(nf, xi, c), NULL, &temp_p[0]);
}
// Solves the NL problem
ceres::Solver::Summary summary;
ceres::Solve(options, &problem, &summary);
// Solves the NL problem
ceres::Solver::Summary summary;
ceres::Solve(options, &problem, &summary);
#ifdef DEBUG
std::cout << summary.BriefReport() << std::endl;
std::cout << summary.BriefReport() << std::endl;
#endif
std::cout << "<<INFO>> found parameters: " << p << std::endl;
// Update the resulting parameter vector
for(int i=0; i<nf->nbParameters(); ++i)
{
p[c*nf->nbParameters() + i] = temp_p[i];
}
}
std::cout << "<<INFO>> found parameters: " << p << std::endl;
nf->setDimY(d->dimY());
nf->setParameters(p);
return true;
nf->setParameters(p);
return true;
}
#endif
void nonlinear_fitter_ceres::set_parameters(const arguments& args)
{
......
......@@ -160,9 +160,9 @@ vec diffuse_function::parametersJacobian(const vec& x) const
void diffuse_function::bootstrap(const data* d, const arguments& args)
{/*
{
// Set the diffuse component
if(params::is_cosine_weighted(d->output_parametrization()))
if(params::is_cosine_weighted(d->output_parametrization()) || args.is_defined("cos-fit"))
{
vec cart(6);
......@@ -185,7 +185,6 @@ void diffuse_function::bootstrap(const data* d, const arguments& args)
}
}
else
*/
{
for(int i=0; i<d->dimY(); ++i)
_kd[i] = std::numeric_limits<double>::max();
......
......@@ -43,9 +43,9 @@ vec beckmann_function::value(const vec& x) const
const double dh2 = dot*dot;
const double expo = exp((dh2 - 1.0) / (a2 * dh2));
if(dot > 0.0 && x[2]*x[5]>0.0)
if(dot > 0.0)
{
res[i] = _ks[i] / (4.0 * x[2]*x[5] * M_PI * a2 * dh2*dh2) * expo;
res[i] = _ks[i] / (4.0 /* x[2]*x[5] */* M_PI * a2 * dh2*dh2) * expo;
}
else
{
......@@ -128,19 +128,19 @@ vec beckmann_function::parametersJacobian(const vec& x) const
{
for(int j=0; j<dimY(); ++j)
{
if(i == j && dot>0.0 && x[2]*x[5]>0.0)
if(i == j && dot>0.0/* && x[2]*x[5]>0.0*/)
{
const double a = _a[i];
const double a2 = a*a;
const double dh2 = dot*dot;
const double expo = exp((dh2 - 1.0) / (a2 * dh2));
const double fac = (4.0 * x[2]*x[5] * M_PI * a2 * dh2*dh2);
const double fac = (4.0 /* x[2]*x[5] */* M_PI * a2 * dh2*dh2);
// df / dk_s
jac[i*nbParameters() + j*2+0] = expo / fac;
// df / da_x
jac[i*nbParameters() + j*2+1] = - _ks[i] * (expo/(4.0*x[2]*x[5])) * ((2* a * dot)/(M_PI*a2*a2*dh2)) * (1 + (dh2 - 1.0)*dot/(a2*dh2*dot));
jac[i*nbParameters() + j*2+1] = - _ks[i] * (expo/(4.0/*x[2]*x[5]*/)) * ((2* a * dot)/(M_PI*a2*a2*dh2)) * (1 + (dh2 - 1.0)*dot/(a2*dh2*dot));
}
else
{
......
......@@ -17,6 +17,7 @@ SUBDIRS = \
nonlinear_fresnel_schlick \
nonlinear_fresnel_normalized_schlick \
nonlinear_fresnel_retroschlick \
nonlinear_shadowing_smith \
nonlinear_function_diffuse \
# nonlinear_function_microfacets \
nonlinear_function_abc \
......
......@@ -47,6 +47,10 @@ int main(int argc, char** argv)
// Get the function file
function* f = NULL;
f = plugins_manager::get_function(args);
if(f == NULL)
{
return 1;
}
if(d != NULL && f != NULL)
{
......
......@@ -30,6 +30,7 @@ int main(int argc, char** argv)
std::cout << " --inc-angle [float] set the incoming light elevation in radian for the polar" << std::endl;
std::cout << " plot export." << std::endl;
std::cout << " --samples [int] set the points used for the polar plot export." << std::endl;
std::cout << " --cos-plot export the BRDF*cosine instead of the BRDF alone." << std::endl;
return 0;
}
......@@ -47,11 +48,21 @@ int main(int argc, char** argv)
// Load a function file
function* f = plugins_manager::get_function(args["input"]) ;
if(f == NULL)
{
return 1;
}
// Create output file
std::ofstream file(args["output"].c_str(), std::ios_base::trunc);
file.precision(10);
// Should I export a BRDF or BRDF*cos ?
// Cannot export a cosine term if no parametrization is defined for the
// input function
const bool cos_plot = args.is_defined("cos-plot") && f->input_parametrization() != params::UNKNOWN_INPUT;
// Load a data file
data* d = NULL ;
if(args.is_defined("data"))
......@@ -88,6 +99,7 @@ int main(int argc, char** argv)
vec v = d->get(i) ;
vec x(f->dimX());
// Convert the data to the function's input space.
if(f->input_parametrization() == params::UNKNOWN_INPUT)
{
memcpy(&x[0], &v[0], f->dimX()*sizeof(double));
......@@ -97,7 +109,18 @@ int main(int argc, char** argv)
params::convert(&v[0], d->input_parametrization(), f->input_parametrization(), &x[0]);
}
vec y2 = f->value(x) ;
// Evaluate the function. I can add the cosine term to the BRDF
// value.
double costerm = 1.0;
if(cos_plot)
{
double cart[6];
params::convert(&x[0], f->input_parametrization(), params::CARTESIAN, cart);
costerm = cart[5]*cart[2];
}
vec y2 = costerm * f->value(x) ;
if(!linear_plot)
{
for(int u=0; u<d->dimX(); ++u)
......
......@@ -24,6 +24,7 @@
<!-- Define the function to use -->
<function name="nonlinear_function_diffuse" />
<function name="nonlinear_function_retrobeckmann">
<parameter name="fresnel" value="./build/libnonlinear_shadowing_smith.so"/>
</function>
<!-- Define the ftting procedure to use -->
......@@ -31,18 +32,18 @@
<!-- Parameters -->
<parameter name="min" value="[0.1, -2, -2]" />
<parameter name="max" value="[1.7, 2, 2]" />
<parameter name="max" value="[0.3, 2, 2]" />
</action>
<action name="data2brdf">
<!-- Input and output arguments of the action -->
<input name="../papers/retro/mesures/original/Bande_orange/3d/633nm/Fichiers_definitifs/densify_helmholtz/Bande_orange_3D__BRDF_min_retro_lobe_dense.alta" />
<input name="../papers/retro/mesures/original/Bande_orange/3d/633nm/Fichiers_definitifs/densify_helmholtz/Bande_orange_3D_dense__nbsgrid_162.alta" />
<output name="./results/3d/retro/half/Bande_orange_beck_back.brdf" />
<!-- Define the function to use -->
<function name="nonlinear_function_diffuse" />
<function name="nonlinear_function_retrobeckmann">
<parameter name="fresnel" value="./build/libnonlinear_fresnel_retroschlick.so"/>
<!--<parameter name="fresnel" value="./build/libnonlinear_shadowing_smith.so"/>-->
</function>
<!-- Define the ftting procedure to use -->
......@@ -50,8 +51,9 @@
<!-- Parameters -->
<parameter name="min" value="[0.1, -2, -2]" />
<parameter name="max" value="[1.7, 2, 2]" />
<parameter name="bootstrap" value="./results/3d/retro/half/Bande_orange_beck_back.brdf" />
<parameter name="max" value="[0.9, 2, 2]" />
<!--<parameter name="bootstrap" value="./results/3d/retro/half/Bande_orange_beck_back.brdf" />-->
<parameter name="cos-fit" value="" />
</action>
<!-- Export the fit -->
......@@ -65,6 +67,7 @@
<parameter name="min" value="[0.1, -2, -2]" />
<parameter name="max" value="[1.7, 2, 2]" />
<parameter name="cos-plot" value="" />
</action>
......@@ -96,13 +99,13 @@
<action name="data2brdf">
<!-- Input and output arguments of the action -->
<input name="../papers/retro/mesures/original/Bande_orange/3d/633nm/Fichiers_definitifs/densify_helmholtz/Bande_orange_3D__BRDF_min_retro_lobe_dense.alta" />
<input name="../papers/retro/mesures/original/Bande_orange/3d/633nm/Fichiers_definitifs/densify_helmholtz/Bande_orange_3D_dense__nbsgrid_162.alta" />
<output name="./results/3d/retro/half/Bande_orange_beck_retro.brdf" />
<!-- Define the function to use -->
<function name="nonlinear_function_diffuse" />
<function name="nonlinear_function_retrobeckmann">
<parameter name="fresnel" value="./build/libnonlinear_fresnel_retroschlick.so"/>
<!--<parameter name="fresnel" value="./build/libnonlinear_shadowing_smith.so"/>-->
<parameter name="retro" value="" />
</function>
......@@ -112,7 +115,8 @@
<!-- Parameters -->
<parameter name="min" value="[0.1, -2, -2]" />
<parameter name="max" value="[1.7, 2, 2]" />
<parameter name="bootstrap" value="./results/3d/retro/half/Bande_orange_beck_retro.brdf" />
<!--<parameter name="bootstrap" value="./results/3d/retro/half/Bande_orange_beck_retro.brdf" />-->
<parameter name="cos-fit" value="" />
</action>
<!-- Export the fit -->
......@@ -126,5 +130,6 @@
<parameter name="min" value="[0.1, -2, -2]" />
<parameter name="max" value="[1.7, 2, 2]" />
<parameter name="cos-plot" value="" />
</action>
</alta>
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