void Optimizer::FitFirstPrincipalComponents(mat& alpha, mat& beta, mat& rho, mat& lamda, InputPtr input, ModelPtr model, MeshPtr mesh, ShapePtr shape, TexturePtr texture, const cv::Mat& ready) { mat alpha_gradient = mat(PrincipalNum, 1, fill::zeros); mat alpha_hessian_inv = mat(PrincipalNum, PrincipalNum, fill::zeros); mat beta_gradient = mat(PrincipalNum, 1, fill::zeros); mat rho_gradient = mat(RhoNum, 1, fill::zeros); mat lamda_gradient = mat(LamdaNum, 1, fill::zeros); vec step(RhoNum, 1); step.rows(0, 2).fill(0.00000006); step.rows(3, 5).fill(0.0002); step.rows(6, 6).fill(2.0); mat step_mat = diagmat(step); // down sampled version cv::Mat down_sampled; pyrDown(ready, down_sampled, Size(IMAGE_WIDTH / 2, IMAGE_HEIGHT / 2)); input = make_shared<InputImage>(down_sampled); model->SetSize(IMAGE_WIDTH / 2, IMAGE_HEIGHT / 2); rho[FOCAL] /= 2; //SetStartingValue(rho, lamda); double para_num = 10; double weight = 1.0 / 900; int counter = 0; while (counter < 1000) { Alpha alpha_para(alpha, input, model, mesh, shape, texture); Beta beta_para(beta, model, mesh, shape, texture); Rho rho_para(rho, input, model, mesh, shape, texture); Lamda lamda_para(lamda, model, mesh, shape, texture); if (counter == 0 || counter % 1000 == 0) { Face3dModel face3d_model(shape, texture); mesh = face3d_model.Construction(alpha, beta); TwoPassZbuffer(rho, lamda, mesh, model); model->EnableIterator(); model->InitialRandomGenerator(); //GenerateRandomPoints(model, HessianRandomNum); //for (int i = 0; i < para_num; ++i) //{ // double variance = shape->GetVariance(i); // mat alpha1 = alpha; // alpha1[i] -= H; // Alpha alpha_para1(alpha1, input, model, mesh, shape, texture); // double first_derivative1 = weight * ComputeIntensityGradient(input, &alpha_para1, i) + 2 * alpha1[i] / variance; // mat alpha2 = alpha; // alpha2[i] += H; // Alpha alpha_para2(alpha2, input, model, mesh, shape, texture); // double first_derivative2 = weight * ComputeIntensityGradient(input, &alpha_para2, i) + 2 * alpha2[i] / variance; // double second_derivative = (first_derivative2 - first_derivative1) / (2 * H); // alpha_hessian_inv(i, i) = 1 / (second_derivative + 2 / variance); //} } // Generate random points GenerateRandomPoints(model, GradientRandomNum); double function_value = 0; function_value = ComputeCost(input, model, alpha_para); ofstream cost; cost.open("first_cost", ios::app); cost << function_value << "\n"; cost.close(); for (int i = 0; i < para_num; ++i) { double variance = shape->GetVariance(i); alpha_gradient[i] = weight * ComputeIntensityGradient(input, &alpha_para, i) + 2 * alpha[i] / variance; } //for (int i = 0; i < 10; ++i) //{ // double variance = texture->GetVariance(i); // beta_gradient[i] = weight *ComputeIntensityGradient(input, &beta_para, i) + 2 * beta[i] / variance; //} //for (int i = 0; i < RhoNum; ++i) //{ // double first_derivative1 = 1.0 / 1000*ComputeIntensityGradient(input, &rho_para, i); // //double variance = rho_para.GetVariance(i); // //double mean = rho_para.GetMean(i); // rho_gradient[i] = first_derivative1;// +2 * (rho[i] - mean) / variance; //} //for (int i = 0; i < LamdaNum-7; ++i) //{ // double first_derivative1 = 1.0 / 1000 * ComputeIntensityGradient(input, &lamda_para, i); // //double variance = lamda_para.GetVariance(i); // //double mean = lamda_para.GetMean(i); // lamda_gradient[i] = first_derivative1; //+2 * (lamda[i] - mean) / variance; //} alpha -= alpha_para.Step*alpha_gradient; //beta -= beta_para.Step*beta_gradient; //rho -= step_mat*rho_gradient; //lamda -= lamda_para.Step*lamda_gradient; //alpha -= 0.00008*alpha_hessian_inv*alpha_gradient; ++counter; } // restore original version input= make_shared<InputImage>(ready); model->SetSize(IMAGE_WIDTH, IMAGE_HEIGHT); rho[FOCAL] *= 2; Face3dModel face3d_model(shape, texture); mesh = face3d_model.Construction(alpha, beta); VisualizeResult(rho, lamda, input, mesh, "first"); }
void Optimizer::FitIllumination(mat& alpha, mat& beta, mat& rho, mat& lamda, InputPtr input, ModelPtr model, MeshPtr mesh, ShapePtr shape, TexturePtr texture, const cv::Mat& ready) { mat lamda_gradient=mat(LamdaNum, 1,fill::zeros); mat lamda_hessian_inv = mat(LamdaNum, LamdaNum, fill::zeros); Face3dModel face3d_model(shape, texture); mesh = face3d_model.Construction(alpha, beta); //VisualizeResult(rho, lamda, input, mesh, 0); TwoPassZbuffer(rho, lamda, mesh, model); model->EnableIterator(); model->InitialRandomGenerator(); // down sampled version cv::Mat down_sampled; pyrDown(ready, down_sampled, Size(IMAGE_WIDTH / 2, IMAGE_HEIGHT / 2)); input = make_shared<InputImage>(down_sampled); model->SetSize(IMAGE_WIDTH / 2, IMAGE_HEIGHT / 2); rho[FOCAL] /= 2; double weight = 1.0 / 1000; int counter = 0; while (counter < 500) { Alpha alpha_para(alpha, input, model, mesh, shape, texture); Beta beta_para(beta, model, mesh, shape, texture); Rho rho_para(rho, input, model, mesh, shape, texture); Lamda lamda_para(lamda, model, mesh, shape, texture); // Generate random points //if (counter == 0 || counter % 1000 == 0) //{ // GenerateRandomPoints(model, HessianRandomNum); // for (int i = 0; i < LamdaNum - 7; ++i) // { // mat lamda1 = lamda; // lamda1[i] -= H; // Lamda lamda_para1(lamda1, model, mesh, shape, texture); // double first_derivative1 = weight*ComputeIntensityGradient(input, &lamda_para1, i); // mat lamda2 = lamda; // lamda2[i] += H; // Lamda lamda_para2(lamda2, model, mesh, shape, texture); // double first_derivative2 = weight* ComputeIntensityGradient(input, &lamda_para2, i); // double second_derivative = (first_derivative2 - first_derivative1) / (2 * H); // lamda_hessian_inv(i, i) = 1 / second_derivative; // } //} GenerateRandomPoints(model, GradientRandomNum); //double function_value = 0; //function_value = ComputeCost(input, model, alpha_para); //ofstream cost; //cost.open("illumination_cost", ios::app); //cost << function_value << "\n"; //cost.close(); for (int i = 0; i < LamdaNum; ++i) { lamda_gradient[i] = weight*ComputeIntensityGradient(input, &lamda_para, i); } lamda -= lamda_para.Step*lamda_gradient; //lamda -= 0.5*lamda_hessian_inv*lamda_gradient; ++counter; } // restore original version input= make_shared<InputImage>(ready); model->SetSize(IMAGE_WIDTH, IMAGE_HEIGHT); rho[FOCAL] *= 2; VisualizeResult(rho, lamda, input, mesh, "illumination"); }