* This algorithm is very similar to the shape fitting in fit_shape_to_landmarks_linear. Instead of the PCA basis, the blendshapes are used, and instead of
* the mean, a current face instance is used to do the fitting from.
* This algorithm is very similar to the shape fitting in fit_shape_to_landmarks_linear.
* Instead of the PCA basis, the blendshapes are used, and instead of the mean, a current
* face instance is used to do the fitting from.
*
* @param[in] blendshapes A vector with blendshapes to estimate the coefficients for.
* @param[in] face_instance A shape instance from which the blendshape coefficients should be estimated (i.e. the current mesh without expressions, e.g. estimated from a previous PCA-model fitting). A 3m x 1 matrix.
boolnon_singular=cv::solve(AtAReg,-A.t()*b,c_s,cv::DECOMP_SVD);// DECOMP_SVD calculates the pseudo-inverse if the matrix is not invertible.
// Because we're using SVD, non_singular will always be true. If we were to use e.g. Cholesky, we could return an expected<T>.
returnstd::vector<float>(c_s);
};
/**
* Fits blendshape coefficients to given 2D landmarks, given a current face shape instance.
* Uses non-negative least-squares (NNLS) to solve for the coefficients. The NNLS algorithm
* used doesn't support any regularisation.
*
* This algorithm is very similar to the shape fitting in fit_shape_to_landmarks_linear.
* Instead of the PCA basis, the blendshapes are used, and instead of the mean, a current
* face instance is used to do the fitting from.
*
* @param[in] blendshapes A vector with blendshapes to estimate the coefficients for.
* @param[in] face_instance A shape instance from which the blendshape coefficients should be estimated (i.e. the current mesh without expressions, e.g. estimated from a previous PCA-model fitting). A 3m x 1 matrix.
* @param[in] affine_camera_matrix A 3x4 affine camera matrix from model to screen-space (should probably be of type CV_32FC1 as all our calculations are done with float).
* @param[in] landmarks 2D landmarks from an image to fit the blendshapes to.
* @param[in] vertex_ids The vertex ids in the model that correspond to the 2D points.
// Copy all blendshapes into a "basis" matrix with each blendshape being a column:
cv::Matblendshapes_as_basis(blendshapes[0].deformation.rows,blendshapes.size(),CV_32FC1);// assert blendshapes.size() > 0 and all of them have same number of rows, and 1 col
basis_rows.colRange(0,num_coeffs_to_fit).copyTo(V_hat_h.rowRange(row_index,row_index+3));// Todo: I think we can remove colRange here, as we always want to use all given blendshapes
row_index+=4;// replace 3 rows and skip the 4th one, it has all zeros
}
// Form a block diagonal matrix $P \in R^{3N\times 4N}$ in which the camera matrix C (P_Affine, affine_camera_matrix) is placed on the diagonal: