<font><font face="courier new,monospace">Greetings<br><br>I'm a researcher enrolled in a project that requires fitting measured data into known functions.<br></font></font><div><font><font face="courier new,monospace">The measured data is the color variation of a point on a material, as the camera and light source moves around the object. </font></font></div>
<div><font><font face="courier new,monospace">So our functions </font></font><font><font face="courier new,monospace">depend on those directions.<br></font></font></div><font><font face="courier new,monospace"><br>A simplistic model is the Lambertian BRDF model that simply says thatthe color value is the dot product of the normal at that point with the incident light direction.<br>
<br>The incident lighting direction and the camera direction are known, they are a discrete set of directions expressed in polar coordinates w := (theta, phi).<br><br>The objective is to find the best parameters of the BRDF model so that it is most correlated with the measured data, this is, to minimize the difference between the measured data and the estimated values.<br>
<br></font></font><div><font><font face="courier new,monospace">I came up with this:<br></font></font></div><font><font face="courier new,monospace"><br> /** This class implements the following NLP.<br> *<br> * Lambert BRDF model<br>
* min sum[i=0, ni-1] sum[o=0, no-1]{ f(N, wi, wo) - T(wi,wo) }<br> * with<br> * f(N, wi, wo) = dot(wi, N)<br> *<br> * note:<br> * T -> texel value for the wi and wo directions<br> * N -> Geometric Normal := {theta_n, phi_n}<br>
* wi -> Incomming light direction := {theta_i, phi_i}<br> * wo -> Outgoing camera direction := {theta_o, phi_o}<br> */<br><br> I defined these boundaries:<br><br> // theta is limited to the upper hemisphere<br>
x_l[THETA_N] = x_l[THETA_i] = x_l[THETA_o] = 0.0;<br> x_u[THETA_N] = x_u[THETA_i] = x_u[THETA_o] = PI/2;<br><br> // phi<br> x_l[PHI_N] = x_l[PHI_i] = x_l[PHI_o] = 0.0;<br> x_u[PHI_N] = x_u[PHI_i] = x_u[PHI_o] = 2*PI;<br>
<br><br> This is the eval_f function:<br><br> // get diretions in cartesian coordinates<br> vec3 N = vec3( sin(x[THETA_N])*cos(x[PHI_N]), sin(x[THETA_N])*sin(x[THETA_N]), cos(x[THETA_N]) );<br> vec3 wi_c = vec3( sin(x[THETA_i])*cos(x[PHI_i]), sin(x[THETA_i])*sin(x[THETA_i]), cos(x[THETA_i]) );<br>
vec3 wo_c = vec3( sin(x[THETA_o])*cos(x[PHI_o]), sin(x[THETA_o])*sin(x[THETA_o]), cos(x[THETA_o]) );<br><br> for each(texel_value t in texel_coordinates)<br> {<br> Number f = dot(wi_c, N);<br> Number T = t.value;<br>
obj_value += f - T;<br> }<br><br><br>And this is the gradient of the objective function, in order to calculate it I had to do the math in Cartesian coordinates, consequently by converting the spherical coordinates to Cartesian a lot of trigonometric functions appear:<br>
(note: all vectors are normalized, the 'r' coordinate in spherical coordinates can be ignored)<br><br>grad_f[THETA_N] = cos(x[THETA_N])*sin(x[THETA_i])*cos(x[PHI_N]-x[PHI_i])-sin(x[THETA_N])*cos(x[THETA_i]);<br>grad_f[PHI_N] = -sin(x[THETA_N])*sin(x[THETA_i])*sin(x[PHI_N]-x[PHI_i]);<br>
grad_f[THETA_i] = sin(x[THETA_N])*cos(x[THETA_i])*cos(x[PHI_N]-x[PHI_i])-cos(x[THETA_N])*sin(x[THETA_i]);<br>grad_f[PHI_i] = -sin(x[THETA_N])*sin(x[THETA_i])*sin(x[PHI_N]-x[PHI_i]);<br>grad_f[THETA_o] = 0.0; <br>grad_f[PHI_o] = 0.0; <br>
<br><br>I haven't specified constraints, so I don't have the Jacobian of the constraints.<br>As for the Hessian of the Lagrangian, I did similar calculations as for the gradient.<br><br></font></font><div><font><font face="courier new,monospace">Running IPOPT gives me an output that is not very satisfactory.</font></font></div>
<div><font><font face="courier new,monospace">Unfortunately I don't have the means to validate the output.<br></font></font></div><font><font face="courier new,monospace"> I know that the value of the IPOPT run give significantly different<br>
values depending on the starting point.<br><br> Can someone assist me on this?<br> Am I doing any mistake?<br> Do I need constraints?<br><br> Best Regards<br>Nuno Silva</font></font><br>